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

不同點 

1:操作對象的不同

Malloc 和 free 是C++/C語言中的標準函數,使用時需要頭文件的支持(malloc.h);而new/delete是C++中的操作符。他們都能夠在C++中動態的分配內存和釋放內存資源。對於一般的數組、結構的動態創建而言沒什麼差別,但是對於非內部數據類的對象而言,光用maloc/free 無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數, 對象消亡之前要自動執行析構函數。由於malloc/free 是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加malloc/free。在使用new的時候,一般會先分配內存,後調用類的構造函數進行初始化,在使用delete的時候也會先調用析構函數刪除對象,後銷燬內存;但是malloc/free就沒有關於構造函數與析構函數操作的步驟;

2:用法上的不同:

函數malloc 的原型如下:
void * malloc(size_t size);
用malloc 申請一塊長度爲length 的整數類型的內存,程序如下:
int *p = (int *) malloc(sizeof(int) * length);
我們應當把注意力集中在兩個要素上:“類型轉換”和“sizeof”。
1、malloc 返回值的類型是void *,所以在調用malloc 時要顯式地進行類型轉換,將void * 轉換成所需要的指針類型。
2、 malloc 函數本身並不識別要申請的內存是什麼類型,它只關心內存的總字節數。
函數free 的原型如下:
void free( void * memblock );
爲什麼free 函數不象malloc 函數那樣複雜呢?這是因爲指針p 的類型以及它所指的內存的容量事先都是知道的,語句free(p)能正確地釋放內存。如果p 是NULL 指針,那麼free
對p 無論操作多少次都不會出問題。如果p 不是NULL 指針,那麼free 對p連續操作兩次就會導致程序運行錯誤。

3:其他方面的不同;

new和delete是操作符,和‘+’,‘-’一樣,同樣可以被重載,當new/delete在類中被重載的時候,可以自定義申請過程,比如記錄所申請內存的總長度,以及跟蹤每個對象的指針。

new是類型安全的;而malloc不是,例如

int *p=new float[100]; 編譯時會指出錯誤,而int* p = (int*)malloc(2*sizeof(float))編譯時無法指出錯誤;

使用new動態創建對象時會自動調用類的構造函數(依據重載類型而定),但是動態創建對象數組時只能調用類的默認構造函數,例如:

Obj *objects = new Obj[100];       // 創建100 個動態對象
不能寫成
Obj *objects = new Obj[100](1);        // 創建100 個動態對象的同時賦初值1
在用delete 釋放對象數組時,留意不要丟了符號‘[]’。例如
delete []objects; // 正確的用法
delete objects; // 錯誤的用法
後者相當於delete objects[0],漏掉了另外99 個對象。

舉個栗子:

// new_vs_malloc.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include<iostream>
using namespace std;
class Obj
{
	public:  
    Obj()   
    { 
		cout<<"Initialization"<<endl; 
	}  
    ~ Obj()  
    {
		cout<<"Destroy"<<endl; 
	}  
    void Initialize()  
    {
		cout<<"Initialization"<<endl; 
	}  
    void  Destroy()  
    {
		cout<<"Destroy"<<endl; 
	} 
};

void  UseMallocFree( )  
{  
    Obj *a  =  (Obj*) malloc(sizeof(Obj));      //  allocate memory   
    a->Initialize();                                    //  initialization  
    // …   
    a->Destroy();                                        // deconstruction   
    free(a);                                               // release memory  
}  
  
void  UseNewDelete( void )  
{  
    Obj *a = new Obj;                                             
    // …   
    delete a;   
}  

int _tmain(int argc, _TCHAR* argv[])
{
	UseMallocFree();
	UseNewDelete();
	cin.get();
	cin.get();
	return 0;
}
運行結果:

                                                                  

類Obj的函數Initialize實現了構造函數的功能,函數Destroy實現了析構函數的功能。函數UseMallocFree中,由於malloc/free不能執行構造函數與析構函數,必須調用成員函數Initialize和Destroy來完成“構造”與“析構”。所以我們不要用malloc/free來完成動態對象的內存管理,應該用new/delete。由於內部數據類型的“對象”沒有構造與析構的過程,對它們而言malloc/free和new/delete是等價的。




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