new和malloc有何區別?

2021-09-27 02:40:24 字數 3215 閱讀 5320

寫這個問題的原因是面試時被問到new和malloc申請的記憶體有何區別,當時沒有回答出來,回來後查閱了很多的部落格,發現自己不會的真的特別多,所以現在自己寫了乙個回答!!!

首先我們大概知道c和c++申請動態記憶體的方式如下:

c:使用malloc、calloc、realloc函式申請動態記憶體,使用free函式釋放申請到的記憶體。申請記憶體空間的標頭檔案是:#include .

c++:使用new操作符申請動態記憶體,使用delete釋放申請到的記憶體。

然後,接下來現在我們來分析一下 new 和 malloc 的不同之處:

. new操作符從自由儲存區(free store)上為物件動態分配記憶體空間,而malloc函式從堆上動態分配記憶體。

自由儲存是c++中通過 new 和 delete 動態分配和釋放物件的抽象概念,通過 new 來申請的記憶體區域可稱為自由儲存區;堆(heap)是c語言和作業系統的術語,堆是作業系統所維護的一塊特殊記憶體,它提供了動態分配的功能,當執行程式呼叫 malloc() 時就會從中分配,之後呼叫 free() 時會把記憶體交還。

問:自由儲存區與堆是兩塊不同的記憶體區域嗎?它們有可能相同嗎?

我在網上看了很多的部落格,他們都說劃分自由儲存區與堆的分界線就是new/delete與malloc/free。然而,儘管c++標準沒有要求,但很多編譯器的new/delete都是以malloc/free為基礎來實現的。那麼藉以malloc實現的new,所申請的記憶體到底是在堆上還是在自由儲存區上?

其實:基本上,所有的c++編譯器預設使用堆來實現自由儲存,也即是預設的全域性運算子new和delete也許會按照malloc和free的方式來被實現,這時藉由new運算子分配的物件,說它在堆上也對,說它在自由儲存區上也正確。但程式設計師也可以通過過載操作符,改用其他記憶體來實現自由儲存,例如全域性變數做的物件池,這時自由儲存區就區別於堆了。我們所需要記住的就是:堆是作業系統維護的一塊記憶體,而自由儲存區是c++中通過new與delete動態分配和釋放物件的抽象概念。堆與自由儲存區並不等價。

. new操作符記憶體分配成功時,返回的是物件型別的指標,型別要求嚴格與物件匹配,無須進行型別轉換,故new是符合型別安全性的操作符。而malloc記憶體分配成功則是返回 void * ,需要通過強制型別轉換將 void* 指標轉換成我們需要的型別,故malloc不是符合型別安全性的操作符。

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

eg:a* dd = new a;

a* dd = (a*) malloc (sizeof(a));

. new記憶體分配失敗時,丟擲bad_alloc異常來報告分配失敗,它不會返回null;malloc分配記憶體失敗時會返回null。

使用new操作符來分配物件記憶體時會經歷三個步驟:

**第一步:**呼叫operator new 函式(對於陣列是operator new)分配一塊足夠大的,原始的,未命名的記憶體空間以便儲存特定型別的物件。

**第二步:**編譯器執行相應的建構函式以構造物件,並為其傳入初值。

**第三步:**物件構造完成後,返回乙個指向該物件的指標。

使用delete操作符來釋放物件記憶體時會經歷兩個步驟:

**第一步:**呼叫物件的析構函式。

**第二步:**編譯器呼叫operator delete(或operator delete)函式釋放記憶體空間。

總之來說,new/delete會呼叫物件的建構函式/析構函式以完成物件的構造/析構。而malloc則不會。

. 使用malloc分配的記憶體,如果在使用過程中發現記憶體不足,可以使用realloc函式進行記憶體重新分配實現記憶體的擴充。realloc會先判斷當前的指標所指向的記憶體是否有足夠的連續空間,如果有,原地擴大可分配的記憶體位址,並且返回原來的位址指標;如果空間不夠,先按照新指定的大小分配空間,將原有資料從頭到尾拷貝到新分配的記憶體區域,而後釋放原來的記憶體區域。而對於new沒有這樣擴充記憶體的處理操作

. 對於new:在operator new丟擲異常以反映乙個未獲得滿足的需求之前,它會先呼叫乙個使用者指定的錯誤處理函式—new-handler。new_handler是乙個指標型別:指向了乙個沒有引數沒有返回值的函式,即為錯誤處理函式。為了指定錯誤處理函式,客戶需要呼叫set_new_handler,這是乙個宣告了的乙個標準庫函式:set_new_handler的引數為new_handler指標,指向了operator new 無法分配足夠記憶體時該呼叫的函式。其返回值也是個指標,指向set_new_handler被呼叫前正在執行(但馬上就要發生替換)的那個new_handler函式。對於malloc,客戶並不能夠去程式設計決定記憶體不足以分配時要幹什麼事,只能看著malloc返回null。

c++ 記憶體分配(new,operator new)

一 、new 運算子和 operator new():

new:指我們在c++裡通常用到的運算子,比如a* a = new a; 對於new來說,有new和::new之分。

operator new():指對new的過載形式,它是乙個函式,並不是運算子。對於operator new來說,分為全域性過載和類過載,全域性過載是void* ::operator new(size_t size),在類中過載形式 void* a::operator new(size_t size)。需要注意的是operator new()完成的操作一般只是分配記憶體,事實上系統預設的全域性::operator new(size_t size)也只是呼叫malloc分配記憶體,並且返回乙個void*指標。而建構函式的呼叫(如果需要)是在new運算子中完成的。

我在前面已經講了new操作符來分配物件記憶體時經歷的三個步驟,這裡我們僅討論前兩步:1.分配記憶體,2.呼叫a()構造物件。

事實上,分配記憶體這一操作就是由operator new(size_t)來完成的,如果類a過載了operator new,那麼將呼叫a::operator new(size_t ),如果沒有過載,就呼叫::operator new(size_t ),全域性new操作符由c++預設提供。因此前面的兩步也可以解釋為:1.呼叫operator new ,2.呼叫建構函式。

暫時寫不下去了,剛做了乙個筆試題,大題gg了,難受,部落格有時間我再繼續補充,找工作好難,共勉~

malloc和new有什麼區別

malloc和new有以下不同 注意 malloc申請的記憶體空間要用free釋放,而new申請的記憶體空間要用delete釋放,不要混用。因為兩者實現的機理不同。有了malloc free為什麼還要new delete?malloc free是c c語言的標準庫函式,new delete是c 的運...

malloc和new有什麼區別

malloc和new有以下不同 注意 malloc申請的記憶體空間要用free釋放,而new申請的記憶體空間要用delete釋放,不要混用。因為兩者實現的機理不同。有了malloc free為什麼還要new delete?malloc free是c c語言的標準庫函式,new delete是c 的運...

new和malloc的區別

1 new 是c 中的操作符,malloc是c 中的乙個函式 2 new 不止是分配記憶體,而且會呼叫類的建構函式,同理delete會呼叫類的析構函式,而malloc則只分配記憶體,不會進行初始化類成員的工作,同樣free也不會呼叫析構函式 3 記憶體洩漏對於malloc或者new都可以檢查出來的,...