new与delete表达式
我们在申请内存和释放内存时,一般直接调用C++的new表达式和delete表达式即可,但只会使用,而不知其内部如何运作以及为何如此运作对于学习者来说并不明智.
new expression
首先,假设我们要创建一个复数对象pc,我们会这样写
Complex* pc = new Complex(1,2);
那么编译器会如何解析这行代码呢?
Complex* pc;
try{
//第一步分配内存,大小为Complex
void * mem = operator new(sizeof(Complex));
//第二步强制转化类型,将申请的空间转化为Complex*
pc = static_cast<Complex*> mem;
//第三步调用类的构造函数
pc->Complex::Complex(1, 2);
}
catch(std::bad_alloc){
//若分配内存失败就不执行
}
由此可见,编译器将内存分配和对象构造分开处理.
我们进一步剖析,operator new函数做了什么.
首先,找到了operator new 声明在new.cpp中;
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__));
之后找到定义;
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
// 如果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表达式,new内部会调用C++函数operator new,在operrator new中,进一步调用malloc.
放一张侯捷大神的图
在这里插入图片描述
delete expression
有了new的基础,这里就放一张大神的图.
在这里插入图片描述