不同點
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是等價的。