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

一、基本概念

 malloc/free

(1)、函數原型及說明

void *malloc(long NumBytes):數組

該函數分配了NumBytes個字節,並返回了指向這塊內存的指針。若是分配失敗,則返回一個空指針NULL。
安全

void free(void *FirstByte): 函數

該函數是將以前用malloc分配的空間還給程序或者是操做系統,也就是釋放了這塊內存,讓它從新獲得自由。
spa

(2)、內存操做

malloc函數的參數是接受須要分配的內存字節數,若是內存可以知足請求量,那麼將會返回:指向被分配的內存塊起始位置;
操作系統

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

 new/free

(1)、操做時發生事件

 new的時候會有兩個事件發生:code

1)、內存被分配(經過operator new 函數);對象

2)、爲被分配的內存調用一個或多個構造函數構建對象。
事件

delete的時候,也有兩件事發生:內存

1)、爲將被釋放的內存調用一個或多個析構函數;  

2)、釋放內存(經過operator delete 函數)。

(2)、特殊應用

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

 所以,若是在調用new時使用了[],則在調用delete時也使用[],若是你在調用new的時候沒有[],那麼也不該該在調用時使用[]。

二、區別

(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 * 轉換成所須要的指針類型;􀂋

(2)、malloc 函數自己並不識別要申請的內存是什麼類型,它只關心內存的總字節數。

void free( void * memblock );

——爲何free 函數不象malloc 函數那樣複雜呢?

這是由於指針p 的類型以及它所指的內存的容量事先都是知道的,語句free(p)能正確地釋放內存。若是p 是NULL 指針,那麼free對p 不管操做多少次都不會出問題。若是p 不是NULL 指針,那麼free 對p連續操做兩次就會致使程序運行錯誤。

new/delete 的使用要點

運算符new 使用起來要比函數malloc 簡單得多,例如:

int *p1 = (int *)malloc(sizeof(int) * length); 
int *p2 = new int[length];

這是由於new 內置了sizeof、類型轉換和類型安全檢查功能。對於非內部數據類型的對象而言,new 在建立動態對象的同時完成了初始化工做。若是對象有多個構造函數,那麼new 的語句也能夠有多種形式。

若是用new 建立對象數組,那麼只能使用對象的無參數構造函數。例如:

Obj *objects = new Obj[100]; // 建立100 個動態對象 不能寫成 
Obj *objects = new Obj[100](1);// 建立100 個動態對象的同時賦初值1

在用delete 釋放對象數組時,留意不要丟了符號‘[]’。例如

delete []objects; // 正確的用法 
delete objects; // 錯誤的用法 後者至關於delete objects[0],漏掉了另外99 個對象
相關文章
相關標籤/搜索