天天看點

delete p和delete[] p的差別

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] 等都沒有調用自身的析構函數,這就是問題的症結所在。