一、本質區別
在C++中引入更多的關鍵字,比如:new和delete;
而malloc和free是庫函數,需要頭文件的支持;
二、申請的空間所在的位置
new關鍵字爲對象分配的空間在自由存儲區內。而molloc是從堆上分配內存;
C/C++內存通常分爲:堆、棧、自由存儲區、全局/靜態存儲區、常量存儲區;
自由存儲區:是C++中通過new和delete動態分配和釋放對象的抽象概念;operator new的底層大多由malloc實現,new和delete是可以C++中的關鍵字,可以對其進行重載(operator new),當new被重載時,內部實現並非只有malloc,此時的內存空間就和堆不同了,這是一塊組合的內存空間。
堆:C語言和操作系統的術語,堆是操作系統維護的特殊的一種內存。
三、返回類型
new運算符返回的是對象類型的指針,是一個確定性的類型,類型嚴格與對象匹配,無須進行類型轉換,故new滿足安全性;而malloc的返回值是一個void*類型,是一個不確定的類型,需要進行類型的轉換。
類型安全很大程度上可以等價於內存安全,類型安全的代碼不會試圖分配在自己沒被授權的內存區域。
四、內存分配失敗時返回值
new內存分配失敗時,會拋出bac_alloc異常,可以使用異常機制來處理;malloc分配內存失敗會返回NULL;所以在c中使用malloc開闢內存都要判斷下返回值類型是否爲空,來確定內存是否開闢成功;
五、是否需要指定內存大小
使用new申請內存分配時不需要指定內存塊的大小,編譯器會根據類型信息自行計算;而malloc需要指定所需內存的大小;
class A
{
cout <<"hello";
};
A *p = new A;
A *p = (A*)malloc(sizeof(A));
六、是否調用構造函數、析構函數
使用new操作符來分配對象內存經歷三個階段
1、通過operator new函數(對於數組是operator new[] 函數)分配一塊足夠大的,原始的,未命名的內存空間以便於存儲特定類型的對象
2、編譯器運行相應的構造函數以構造對象,併爲其傳入初值
3、對象構造完成後,返回一個指向該對象的指針
使用delete操作符來釋放對象內存時會經歷兩個階段
1、調用對象的析構函數
2、通過函數operator delete釋放內存
使用new和delete會調用對象的構造函數/析構函數。而malloc不會。
七、new與malloc是否可以相互調用
operator new和operator delete的實現可以基於malloc,free;反過來,malloc和free的實現不可以調用new和delete。下面是編寫operator new/operator delete的一種簡單方式
void* operator new (size_t size)
{
if(void *p = malloc(size))
{
return p;
}
else
throw bad_alloc();
}
void operator delete(void *p)
{
free(p);
}
八、對數組的處理
C++提供了new[]與delete[]對數組專門的處理;有new[]分配對應就需要delete[]進行釋放,否則只會對數組中的第一個對象進行釋放,會造成內存泄露。
A *ptr = new A[10];//分配十個對象
delete[] ptr;
上面已經說過,malloc需要指定開闢內存的大小,它並不知道這塊內存上存放的是否是數組,反正就是給你一塊內存並且返回一個內存地址;所以如果要動態分配一個數組的內存,還需要我們手動自定數組的大小;
int *ptr = (int *)malloc(sizeof(int)*10);
九、是否可以被重載
operator new/operator delete可以被重載。標準庫是定義了operator new函數和operator delete函數的8個重載版本
//這些版本可能拋出異常
void * operator new(size_t);
void * operator new[](size_t);
void * operator delete (void * )noexcept;
void * operator delete[](void *0)noexcept;
//這些版本承諾不拋出異常
void * operator new(size_t ,nothrow_t&) noexcept;
void * operator new[](size_t, nothrow_t& );
void * operator delete (void *,nothrow_t& )noexcept;
void * operator delete[](void *0,nothrow_t& )noexcept;
而malloc/free不允許重載
十、能夠直觀地重新分配內存
使用malloc分配的內存後,如果在使用過程發現內存不足,可以使用realloc函數進行內存重新分配實現內存的擴容;realloc首先判斷當前的指針所指內存是否有足夠的連續空間,如果有,原地擴大可分配的內存地址,並且返回原來的地址指針;如果空間不夠,先按照新指定的大小分配空間,將原來有的數據從頭到尾拷貝到新分配的內存區域,而後釋放原來的內存區域。
new沒有這樣直觀的配套設施來擴充內存。