new和delete運delete和delete[]&nb…

new和delete運算符用於動態分配和撤銷內存的運算符

new用法:

          1.     開闢單變量地址空間

               1)new int;  //開闢一個存放數組的存儲空間,返回一個指向該存儲空間的地址.int *a = new int 即爲將一個int類型的地址賦值給整型指針a. 

               2)int *a = new int(5) 作用同上,但是同時將整數賦值爲5

          2.     開闢數組空間

               一維: int *a = new int[100];開闢一個大小爲100的整型數組空間

               二維: int **a = new int[5][6]

               三維及其以上:依此類推.

         一般用法: new 類型 [初值]

delete用法:

          1. int *a = new int;

               delete a;   //釋放單個int的空間

          2.int *a = new int[5];

               delete [] a; //釋放int數組空間

 

          要訪問new所開闢的結構體空間,無法直接通過變量名進行,只能通過賦值的指針進行訪問.

          用new和delete可以動態開闢,撤銷地址空間.在編程序時,若用完一個變量(一般是暫時存儲的數組),下次需要再用,但卻又想省去重新初始化的功夫,可以在每次開始使用時開闢一個空間,在用完後撤銷它.
new\delete玩的是對象,而malloc\free僅僅是內存空間而已

2 對於除去對象意外的其他情況,比如int和float等
int* Array=new int[10];和int* Array=malloc(sizeof(int)*10);只存在使用技巧的差別,沒有本質的差別。

3 最後也提醒你new\delete和malloc\free只能成對使用,不能混了。

 


malloc/free和new/delete的區別


malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。

對於非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。

因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以及一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。

我們先看一看malloc/free和new/delete如何實現對象的動態內存管理,見下面示例。


class Obj
{
public :
    Obj(void){ cout << “Initialization” << endl; }
    ~Obj(void){ cout << “Destroy” << endl; }
    void Initialize(void){ cout << “Initialization” << endl; }
    void Destroy(void){ cout << “Destroy” << endl; }
};

void UseMallocFree(void)
{
    Obj  *a = (obj *)malloc(sizeof(obj));   // 申請動態內存
    a->Initialize();                        // 初始化
    //…
    a->Destroy();   // 清除工作
    free(a);        // 釋放內存
}

void UseNewDelete(void)
{
    Obj  *a = new Obj;  // 申請動態內存並且初始化
    //…
    delete a;           // 清除並且釋放內存
}


類Obj的函數Initialize模擬了構造函數的功能,函數Destroy模擬了析構函數的功能。函數UseMallocFree中,由於malloc/free不能執行構造函數與析構函數,必須調用成員函數Initialize和Destroy來完成初始化與清除工作。函數UseNewDelete則簡單得多。

所以我們不要企圖用malloc/free來完成動態對象的內存管理,應該用new/delete。由於內部數據類型的“對象”沒有構造與析構的過程,對它們而言malloc/free和new/delete是等價的。

既然new/delete的功能完全覆蓋了malloc/free,爲什麼C++不把malloc/free淘汰出局呢?這是因爲C++程序經常要調用C函數,而C程序只能用malloc/free管理動態內存。
如果用free釋放“new創建的動態對象”,那麼該對象因無法執行析構函數而可能導致程序出錯。如果用delete釋放“malloc申請的動態內存”,理論上講程序不會出錯,但是該程序的可讀性很差。所以new/delete必須配對使用,malloc/free也一樣。 


delete和delete[] 的區別


我的理解:對於一個數組,delete和delete[]都可以釋放內存空間,但是隻有delete[]纔會調用每一個數組元素的析構函數,而delete只能調用第一個數組元素的析構函數。對於基本數據類型,沒有析構函數,所以使用delete和delete[]沒有區別。

網上搜到的一個解答,原始出處是http://bbs.chinaunix.net/
C++告訴我們在回收用 new 分配的單個對象的內存空間的時候用 delete,回收用 new[] 分配的一組對象的內存空間的時候用 delete[]。

樓主的這個問題提得很好。很多人注意到了這個問題,但是卻不清楚爲什麼要這樣做,不這樣做行不行。

關於 new[] 和 delete[],其中又分爲兩種情況:(1) 爲基本數據類型分配和回收空間;(2) 爲自定義類型分配和回收空間。

對於 (1),上面提供的程序已經證明了 delete[] 和 delete 是等同的。但是對於 (2),情況就發生了變化。請看下面的程序。


#include
using namespace std;

class T {
public:
  T() { cout << "constructor" << endl; }
  ~T() { cout << "destructor" << endl; }
};

int main()
{
  const int NUM = 3;

  T* p1 = new T[NUM];
  cout << hex << p1 << endl;
  //  delete[] p1;
  delete p1;

  T* p2 = new T[NUM];
  cout << p2 << endl;
  delete[] p2;
}


大家可以自己運行這個程序,看一看 delete p1 和 delete[] p1 的不同結果,我就不在這裏貼運行結果了。

從運行結果中我們可以看出,delete p1 在回收空間的過程中,只有 p1[0] 這個對象調用了析構函數,其它對象如 p1[1]、p1 [2] 等都沒有調用自身的析構函數,這就是問題的癥結所在。如果用 delete[],則在回收空間之前所有對象都會首先調用自己的析構函數。

基本類型的對象沒有析構函數,所以回收基本類型組成的數組空間用 delete 和 delete[] 都是應該可以的;但是對於類對象數組,只能用 delete[]。對於 new 的單個對象,只能用 delete 不能用 delete[] 回收空間。

所以一個簡單的使用原則就是:new 和 delete、new[] 和 delete[] 對應使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章