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的基礎,這裏就放一張大神的圖.