array new 與 array deletedelete

之前在看C++書和上C++課的時候能夠看到數組

delete[] pointer;

的用法,而大多數對於這個用法沒有具體的解釋,可能是看到:函數

有一個delete運算符的特殊語法,能夠釋放動態分配的數組內存:操作系統

delete[] p_numbers;

方括號告訴編譯器,指針指向了一個數組,而不是單個值。設計

引文自:《C++程序設計:現代方法》,14.2 指針和數組指針

也沒有說明若是缺乏[]會帶來的後果,猜測是內存泄露,可是不明就裏,因而給我來帶了C++內存管理詭譎的印象。不過最近侯捷先生的講解卻非常清晰。調試

下方所說Complex類爲僅包含兩個double類型成員,String僅含一個char類型指針。code

構造

首先說的是構造,以Complex類爲例:對象

Complex *c = new Complex(1,2);

執行過程爲:blog

Complex *c;
void* mem = operator new( sizeof(Complex) ); //內部調用malloc(n),分配內存
c = static_cast<Complex*>(mem);              //類型轉換
c->Complex::Complex(1,2);                    //→Complex::Complex(c,1,2),構造函數

那麼在內存中執行的時候分配內存爲:內存

紅色部分爲操做系統分配之Cookie,藍色部分爲填充位,目的是爲了讓整個長度爲16的倍數。灰色區域內數據僅在Debug模式下出現,綠色區域爲對象所佔長度。可計算,Debug模式下的Complex實例長度爲:

8[兩個雙精度浮點實數] + (32+4)[調試模式] + (4×2)[Cookie] → 52 + 12[填充] → 40H

那麼此時向操做系統取內存時Cookie末位置1,即Cookie爲00000041,釋放時末位置0。之因此保持16(10H)的倍數即如此。

Release下的String類型長度則爲:

4[指針] + (4×2)[Cookie] → 12 + 4[填充] → 10H

釋放

執行

String *s = new String(1,2);
…
delete s;

delete s的時候會:

String::~String(s);     //析構函數
operator delete(s);     //釋放內存,其內部調用free(s)

即執行String類析構函數後釋放內存,釋放Cookie標記段。看起來彷佛沒什麼問題。

數組

看一下

Complex *c = new Complex [3];

String *s = new String [3];

的內存結構,能夠發現是這樣的:

在頂部多存儲了一個數組長度。那麼執行deletedelete[]有什麼區別呢?是這樣的:

能夠看到,對於內存而言,delete必定會將Cookie標記段給釋放掉,若是是相似Complex的數組,那麼使用deletedelete[]的效果是一致的,可是針對String這類含指針類型的數組,使用delete僅執行首次析構,也就是在這裏出現了內存泄漏。


最近怎麼關心內存泄漏了?

程序跑了一夜泄漏了8G內存,不關心一下怎麼得了。

相關文章
相關標籤/搜索