天天看點

new與malloc之間的差別

1、new操作符從自由存儲區上為對象動态配置設定記憶體空間,而malloc函數從堆上動态配置設定記憶體。自由存儲區是c++基于new操作符的一個抽象概念,凡是通過new操作符進行記憶體申請,該記憶體即為自由存儲區。而堆是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用于程式的記憶體動态配置設定,c語言使用malloc從堆上配置設定記憶體,使用free釋放已配置設定的對應記憶體。

自由存儲區是否可以是堆?這取決于operate new 的實作細節。自由存儲區不僅僅可以是堆,還可以是靜态存儲區,這取決于operate new 在哪裡為對象配置設定記憶體。

2、傳回類型安全性

new操作符記憶體配置設定成功時,傳回的是對象類型的指針,類型嚴格與對象相比對,無須進行類型轉換,故new是符合類型安全性的操作符。而malloc記憶體配置設定成功則是傳回void*,需要通過強制類型轉換将void*指針轉換成我們需要的類型。

3、記憶體配置設定失敗時的傳回值

new記憶體配置設定失敗時,會抛出bac_alloc異常,它不傳回NULL;malloc配置設定記憶體失敗時傳回NULL.

是以在new配置設定記憶體後使用判别是否為null完全是無用的,如果配置設定失敗的話,他會出現異常。

4、是否需要指定記憶體的大小

使用new操作符申請記憶體配置設定時無須指定記憶體塊的大小,編譯器根據類型資訊自行計算,而malloc則需要顯式第指出所需的記憶體尺寸。

5、是否調用構造函數/析構函數

使用new操作符來配置設定對象記憶體時會經曆三個步驟

第一步、調用operate new函數配置設定一塊足夠大的、原始的、未命名的記憶體空間以便存儲特定類型的對象;

第二部、編譯器運作相應的構造函數以構造對象,并為其傳入初值;

第三部、對象構造完成後,傳回一個指向該對象的指針。

使用delete操作符來釋放對象時的兩個步驟:

第一步、調用對象的析構函數;

第二部、編譯器調用operate delete函數釋放對象記憶體空間

總之來說,new/delete會調用對象的構造函數/析構函數以完成對象的構造/析構。而malloc則不會

是以,malloc/free來處理C++的自定義類型不合适,其實不止自定義類型,标準庫中凡是需要構造/析構的類型都不合适。

6、對數組的處理

int *p = new int[10];//配置設定大小為10的int型數組
delete []p;
           

new對數組的支援展現在它會分别調用構造函數初始化每一個數組元素,釋放對象時為每個對象調用析構函數。delete[]要與new[]配套使用,不然會出現數組對象部分釋放的對象,造成記憶體洩漏。

至于malloc,它并不知道你在這塊記憶體上要放的是數組還是别的東西,反正它就時給你一塊記憶體,再給你個記憶體位址就完事。是以如果要動态配置設定一個數組的記憶體,還需要手動自定義數組的大小。

7、new與malloc是否可以互相調用

operate new/operatedelete的實作可以基于malloc,而malloc的實作不可以去調用new。

8、是否可以被重載

operatenew/operate delete可以被重載。

operate new /operate delete可以被重載

而malloc、free不能重載

9、能夠直覺地重新配置設定記憶體

使用malloc配置設定的記憶體後,如果在使用的過程中發現記憶體不足,可以使用realloc函數進行記憶體重新配置設定實作記憶體的擴充。realloc先判斷目前的指針所指記憶體是否有足夠的連續空間,如果有,原地擴大可配置設定的記憶體位址,并且傳回原來的位址指針;如果空間不夠,先按照新制定的大小配置設定記憶體空間,将原有資料從頭到尾拷貝到新配置設定的記憶體區域,而後釋放原來的記憶體區域

10、客戶處理記憶體配置設定不足

在operate new抛出異常以反映一個未獲得滿足的需求前,它會先調用一個使用者指定的錯誤處理函數,這就是new-handler。

try
	{
		int *a = new int();
	}catch(bad_alloc)
	{
		//do something
	}
           

對于malloc,客戶并不能夠去程式設計決定記憶體不足以配置設定時要幹什麼事,隻能看着malloc傳回NULL

new與malloc之間的差別

繼續閱讀