通常在delete[]一個數組時,編譯器要按順序作如下兩件事情:
1. 對每個數組元素調用解構函式
2. 釋放對象數組所佔記憶體
注意這是彼此獨立的兩步.
在第2步.編譯器只需簡單地把數組首地址告訴作業系統,作業系統內部有記憶體申請情況的記錄(每個申請記憶體段的首地址,長度,etc..),因此會正確地釋放掉記憶體.注意整個數組所佔記憶體是一次釋放掉的,而不是每個元素釋放一次.事實上,在這一步編譯器無需知道數組元素個數.
當然在第1步確實需要知道元素個數.編譯器會把元素個數放在分配的那塊記憶體的前面,結構如下所示
n object1 object2 ... objectn
不要把這個n和數組記憶體長度混淆起來.前者是編譯器管理的,後者是作業系統管理的.(如果知道對象的size,是可以從後者計算出前者.遺憾的是,作業系統沒有API提供所申請的記憶體段的長度,編譯器只好自己記錄)
要注意的是,如果數組元素沒有顯式解構函式(例如char),那麼編譯器就無需作第1步了.在這種情況下,編譯器根本不需要知道數組個數,因此就偷懶不再在數組前面放元素個數n了.
另外,提醒C++程式員 delete [] p;語句中delete和[]之間一定要有空格
舉例如下:
class TestA
{
public:
TestA(){a=new int(1);}
~TestA(){delete a;}
int* a;
};
int *pInt = new int[100];
memset(pInt, 0, 100*sizeof(int));
int* pr = pInt-1;
int size = *pr;//此處size的值不是100,說明數組前面沒有加上數組個數(因為int不需要顯示解構函式)
delete []pInt;
TestA* pArT = new TestA[100];
size = sizeof(TestA) * 100;
int* pp = (int*)(pArT) - 1;
size = *pp;//此處size的值是100,說明數組前面加上了數組個數
delete []pArT;
此代碼再BCB2010中驗證過!
本文轉載:http://blog.csdn.net/lcfeng1982/article/details/8106719