malloc/free和new/delete它們都可用於申請動態內存和釋放內存,但是它們卻有區別:
(1)malloc與free是C++/C語言的內存分配標準庫函數,屬於stdlib庫;new/delete是C++的操作運算符;
(2)new 不止是分配內存,而且會調用類的構造函數,同理delete會調用類的析構函數,而malloc則只分配內存,不會進行初始化類成員的工作,同樣free也不會調用析構函數;
例如:
- 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。
(3)內存泄漏對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個文件的那一行,而malloc沒有這些信息。
(4)返回類型不同:函數malloc 的原型爲void * malloc(size_t size),用malloc 申請一塊長度爲length 的整數類型的內存,返回類型void類型指針(所以在使用malloc的時候你必須手動轉換爲相應的類型)。而new 返回指定類型的指針,並且可以自動計算所需要大小;
注:爲什麼free函數不象malloc函數那樣複雜呢?這是因爲指針p的類型以及它所指的內存的容量事先都是知道的,語句free(p)能正確地釋放內存。如果p是NULL指針,那麼free對p無論操作多少次都不會出問題。如果p不是NULL指針,那麼free對p連續操作兩次就會導致程序運行錯誤。
例如:
- int *p;
- p = new int; //返回類型爲int* 類型(整數型指針),分配大小爲 sizeof(int);
- 或:
- int* parr;
- parr = new int [100]; //返回類型爲 int* 類型(整數型指針),分配大小爲 sizeof(int) * 100;
- 而 malloc 則必須由我們計算要字節數,並且在返回後強行轉換爲實際類型的指針。
- int* p;
- p = (int *) malloc (sizeof(int));//這裏有兩點需要注意:(1)必須自己手動轉換;(2)必須用sizeof計算空間大小
- //用malloc分配連續的空間
- int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100個整數的內存空間。
(5)new和malloc雖然都是申請內存,但申請的位置不同,new的內存從free store分配,而malloc的內存從heap分配(詳情請看ISO14882的內存管理部分),free store和heap很相似,都是動態內存,但是位置不同,這就是爲什麼new出來的內存不能通過free來釋放的原因。不過微軟編譯器並沒有很好的執行標準,很有可能把free store和heap混淆了,因此,free有時也可以;
(6)new是類型安全的,而malloc不是。
例如:
- int* p = new float[2]; // 編譯時指出錯誤
- int* p = malloc(2*sizeof(float)); // 編譯時無法指出錯誤
- new operator 由兩步構成,分別是 operator new 和 construct
幾個注意點:
(1)把new和delete與malloc和free混在一起用也是個壞想法。對一個用new獲取來的指針調用free,或者對一個用malloc獲取來的指針調用delete,其後果是不可預測的;
(2)delete數組的時候忘了 “[ ]”,容易遺漏對象,造成內存泄露;
(3)malloc申請空間時,不對空間進行檢查,造成不可預料的錯誤。
(4)如果用new 創建對象數組,那麼只能使用對象的無參數構造函數。即沒有默認構造函數的類,不能用new來創建數組。
(5)在delete一個變量後,還要跟上賦值爲0。例:cathouse = new cat(i); delete cathouse[i]; cathouse[i]=0;