c++源码之标准库new,operatornew,placementnew,arraynew
在c++中管理内存的⼀些⼿段与细节
那么这篇博客的内容主要是在学习了jjhou⽼师的内存管理后我⾃⼰总结的⼀些知识点,关于侯捷⽼师的内存管理的内容可以⾃⼰搜索那么直接进⼊正题了
依照bjarne的c++ programming language的11.2.3章节所说,new ,delete,operator new,operator delete的实现在< new >头⽂件中
那么在gcc的⽂件中确实含有new的头⽂件内容确实也有 operator new的声明
void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
__attribute__((__externally_visible__));
void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
__attribute__((__externally_visible__));
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
说明⼀下 new的时候发⽣什么
⾸先调⽤operator new函数 (此函数可以重载达到⾃⼰分配内存的⽬的)
然后将指针转换为 obj 的对应类型
最后调⽤对象的 构造函数
如果失败 抛出bad_alloc异常
那么 operator new 到底做了些什么呢? 在gcc的 ⽂件中
我们到了 operator new 的源码
/
/头⽂件先忽略
using std::new_handler;
using std::bad_alloc;// using 声明
#if _GLIBCXX_HOSTED// 如果有这个宏使⽤ std的malloc
using std::malloc;
#else// 没有则使⽤c语⾔的malloc
// A freestanding C runtime may not provide "malloc" -- but there is no
// other reasonable way to implement "operator new".
extern"C"void *malloc (std::size_t);
#endif
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
// new_handler 以后说明,但是可以看出⾸先我们根据⼊⼝参数 sz的⼤⼩分配内存,
// 如果sz为0 则令其为1 ,然后在while循环中调⽤malloc申请内存
// 直到申请成功或者抛出异常或者 abort
/* malloc (0) is unpredictable; avoid it.  */
if (sz == 0)
sz = 1;
while (__builtin_expect ((p = malloc (sz)) == 0, false))
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
return p;
}
所以 new expression 调⽤了operator new函数 ⽽operator 调⽤了malloc函数
再来看对应的delete(这⾥只放简化的代码)
operator delete(void* ptr) _GLIBCXX_USE_NOEXCEPT
{
std::free(ptr);
}
所以new与malloc的区别也很明显了
new 的过程是
//调⽤ operator new 函数
1. void * tmp_point = ::operator new( sizeof( obj ) ) ;
// 更改 指针的属性
2. obj * point = static_cast
2.placement new
先源码 内容在 < new > 头⽂件当中
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }
可以看到 placement new 什么内存都没有申请 只是直接返回 指针
那么placement new的步骤和new的步骤像只是没有申请任何的内存但是调⽤了构造函数
当我们使⽤
obj p = new( alreadyExistPoint )obj()
意味着在已经分配内存的 内容⾥调⽤obj的构造函数
那么步骤是这样的
//调⽤ 重载的 operator new 函数
1. void * tmp_point = ::operator new( sizeof( obj ) ,alreadyExistPoint) ;
// 更改 指针的属性
2. obj * point = static_cast
molloc函数// Default placement versions of operator delete.
//实现没有到但是原理⼀定类似于 operator delete 只是被重载了⽽已
inline void operator delete  (void*, void*) _GLIBCXX_USE_NOEXCEPT { }
3.array new
先上源码
_GLIBCXX_WEAK_DEFINITION void*
operator new[] (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
return ::operator new(sz);
}
这⾥是我⾃⼰有疑问的地⽅
我们知道array new是对new了⼀个数组的对象,并且调⽤其中的默认构造函数
⽽且array new必须和array delete成对的使⽤,但是源码部分没有展⽰出对象多次调⽤构造函数 这部分内容仍然需要我实⼒再进⼀步才能解答

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。