operator new 和 operator delete函數有兩個重載版本,每個版本支援相關的new表達式和delete表達式:
void* operator new (size_t); // allocate an object
void* operator new [] (size_t); // allocate an array
void operator delete (void*); // free an oject
void operator delete [] (void*); // free an array
熟悉C的朋友看到這裡可能會很奇怪:
在C中釋放記憶體用free(void *)【注意這裡隻有一個參數void *】
為什麼到了C++裡會出現兩個!按理說delete 會調用free釋放記憶體的啊?
另外delete []是如何知道删除的對象個數的?
《高品質C++程式設計指南》這麼說:
在用delete 釋放對象數組時,留意不要丢了符号‘[]’。例如:
delete []objects; // 正确的用法
delete objects; // 錯誤的用法
後者相當于delete objects[0],漏掉了另外99 個對象
關于 new[] 和 delete[],其中又分為兩種情況:(1) 為基本資料類型配置設定和回收空間;(2) 為自定義類型配置設定和回收空間。
對于 (1),下面提供的程式可以證明 delete[] 和 delete 是等同的。
#include <iostream>
using namespace std;
int main()
{
int *p = new int;
delete []p; // 和delete p等價
p = NULL;
cout << "\n===============================\n";
int *q = new int[10];
delete q; // 和delete []q等價
q = NULL;
return 0;
}
但是對于 (2),情況就發生了變化。請看下面的程式。
#include <iostream>
using namespace std;
class T
{
public:
T(){ cout << "constructor" << endl; }
~T(){ cout << "destructor" << endl; }
};
int main()
{
const int NUM = 3;
T *p = new T[NUM];
cout << hex << p << endl;
delete[] p;
//delete p; //error, debug assertion failed!
return 0;
}
從運作結果中我們可以看出,delete p在回收空間的過程中,隻有 p[0] 這個對象調用了析構函數,其它對象如 p[1]、p[2] 等都沒有調用自身的析構函數,這就是問題的症結所在。