new/delete 與malloc/free的區別與聯繫

一、基本概念

     malloc/free:

1、函數原型及說明:

      void *malloc(long NumBytes):該函數分配了NumBytes個字節,並返回了指向這塊內存的指針。如果分配失敗,則返回一個空指針(NULL)

      void free(void *FirstByte): 該函數是將之前用malloc分配的空間還給程序或者是操作系統,也就是釋放了這塊內存,讓它重新得到自由。

 

2.內存操作:

    malloc函數的參數是接受需要分配的內存字節數,如果內存能夠滿足請求量,那麼將會返回:指向被分配的內存塊起始位置

     free函數釋放的是指針指向的內存(不是釋放的指針本身,不會刪除指針本身),其中指針必須指向所釋放內存空間的首地址

 

new/free:

1.操作時發生事件:

     new的時候會有兩個事件發生:1).內存被分配(通過operator new 函數)  2).爲被分配的內存調用一個或多個構造函數構建對象

     delete的時候,也有兩件事發生:1).爲將被釋放的內存調用一個或多個析構函數  2).釋放內存(通過operator delete 函數)

2.特殊應用:

   使用delete是未加括號,delete便假設刪除對象是單一對象。否則便假設刪除對象是個數組

   因此,如果在調用new時使用了[],則在調用delete時也使用[],如果你在調用new的時候沒有[],那麼也不應該在調用時使用[]。

 

二、malloc/free 和new/delete的本質區別:

1.malloc/free是C/C++語言的標準庫函數,new/delete是C++的運算符

2.new能夠自動分配空間大小

3.對於用戶自定義的對象而言,用maloc/free無法滿足動態管理對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。因此C++需要一個能對對象完成動態內存分配和初始化工作的運算符new,以及一個能對對象完成清理與釋放內存工作的運算符delete---簡而言之 new/delete能進行對對象進行構造和析構函數的調用進而對內存進行更加詳細的工作,而malloc/free不能。

 

三、聯繫

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

 

四、使用範例

 

void * malloc(size_t size);

用malloc 申請一塊長度爲length 的整數類型的內存,程序如下:

int *p = (int *) malloc(sizeof(int) * length); 

我們應當把注意力集中在兩個要素上:“類型轉換”和“sizeof”。

1. malloc 返回值的類型是void *,所以在調用malloc 時要顯式地進行類型轉換,將void * 轉換成所需要的指針類型。


1、new 是c++中的操作符,malloc是c 中的一個函數

2、new不止是分配內存,而且會調用類的構造函數,同理delete會調用類的析構函數,而malloc則只分配內存,不會進行初始化類成員的工作,同樣free也不會調用析構函數

3、內存泄漏對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個文件的那一行,而malloc沒有這些信息。

4.new可以看成兩個動作:1。分配內存(相當於malloc)2。引發構造函數。

new   是個操作符,和什麼"+","-","="...有一樣的地位.

malloc是個分配內存的函數,供你調用的.

new是保留字,不需要頭文件支持.

malloc需要頭文件庫函數支持.

new   建立的是一個對象,

malloc分配的是一塊內存.

new建立的對象你可以把它當成一個普通的對象,用成員函數訪問,不要直接訪問它的地址空間

malloc分配的是一塊內存區域,就用指針訪問好了,而且還可以在裏面移動指針.

5、new 和 malloc效率比較

new 有三個字母, malloc有六個字母

new可以認爲是malloc加構造函數的執行。

new出來的指針是直接帶類型信息的。

而malloc返回的都是void指針。

一:new delete 是運算符,malloc,free是函數

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 = newObj;    //申請動態內存並且初始化

//…

deletea;            // 清除並且釋放內存

}

示例用malloc/free和new/delete如何實現對象的動態內存管理

類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也一樣。

二:new delete在實現上其實調用了malloc,free函數。

三:new operator除了分配內存,還要調用構造函數。

malloc函數只是負責分配內存。


發佈了42 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章