-
new的工作
當我們在使用new來創建對象的時候
Complex* pc = new Complex(1,2);
new 會先爲對象分配一塊內存,接着調用構造函數。
try{
void* mem = operator new(sizeof(Complex)); //創建指針 //operator new()是重載了::operator new()
//operator new() 內部調用了 malloc()
pc = static_cast<Complex*>(mem); //指針強轉
pc->Complex::Complex(1,2);
//注意:一般來說,只有編譯器才能像這樣直接調用構造函數的(但可以直接調用析構函數)
//如果想直接調用ctor,可運用 placement new:
// new(pc)Complex(1,2);
}
catch(std::bad_alloc){
}
-
delete的工作
當我們在使用delete來釋放對象的時候
delete pc;
delete 會先調用析構函數,接着釋放內存
pc->~Complex();
operator delete(pc); //operator delete()內部調用 free()
-
array new 與 array delete
Complex* pc = new Complex[3]; //喚起3次ctor(構造函數)
delete[] pc; //喚起3次dtor(析構函數)
如果釋放時忘記 [ ]
delete pc; //喚起1次dtor(析構函數) => 造成內存泄露
從上圖中可看到,new在堆區開闢的空間不僅僅是整個數據的字節大小,還在頭尾附帶了一些數據;
另外,對於非對象數組(這裏是整型數組),不存在析構函數,所以釋放的時候不用加上 [ ] 。
計算new開闢的空間大小:
Debugger Header(32) + no man land (4) = 36 bytes
標記大小"3"的字節爲 4 bytes
1個Demo大小爲 3*4 = 12 bytes,3個Demo大小爲 36 bytes
頭尾的"61h"大小爲 4*2=8 bytes
整合 = 36 + 4 + 36 + 8 = 84 bytes
不滿足16倍數,所以要加上12bytes的Pad
因此整個空間大小 = 84 + 12 = 96 bytes