new 與malloc的區別

2021-08-25 21:21:41 字數 3999 閱讀 6958

學過c++和c語言的一般都會對程式語言中的記憶體分配有點小困惑,malloc和new到底有哪些鉅細的差別?一些同學問過這相似的問題,彭剛老師上課也講過。我總結整理了一下,希望看過本文能明白,現將區別羅列如下:

1、malloc與free是c++/c語言的記憶體分配標準庫函式,屬於stdlib庫;new/delete是c++的操作運算子。它們都可用於申請動態記憶體和釋放記憶體。 

2、對於非內部資料型別的物件而言,光用maloc/free無法滿足動態物件的要求。物件 在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc/free是庫函式而不是運算子,不在編譯器控制許可權之內,不能夠 把執行建構函式和析構函式的任務強加於malloc/free。 

3、c++語言需要乙個能完成動態記憶體分配和初始化工作的運算子new,以及乙個能完成清理與 釋放記憶體工作的運算子delete。注意new/delete不是庫函式,new 不止是分配記憶體,而且會呼叫類的建構函式,同理delete會呼叫類 的析構函式,而malloc則只分配記憶體,不會進行初始化類成員的工作,同樣free也不會呼叫析構函式。

4、c++程式經常要呼叫c函式,而c程式只能用malloc/free管理動態記憶體;

6、 記憶體洩漏對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個檔案的那一行,而malloc沒有這些資訊。

7、 new可以認為是malloc加建構函式的執行。

new出來的指標是直接帶型別資訊的, 而malloc返回的都是void指標。 

8、new是保留字,不需要標頭檔案支援;malloc需要標頭檔案庫函式支援。

new 建立的是乙個物件;malloc分配的是一塊記憶體。

new建立的物件你可以把它當成乙個普通的物件,用成員函式訪問,不要直接訪問它的位址空間;malloc分配的是一塊記憶體區域,就用指標訪問好了,而且還可以在裡面移動指標.

簡而言之:

new   是乙個操作符,可以過載   

malloc是乙個函式,可以覆蓋   

new   初始化物件,呼叫物件的建構函式,對應的delete呼叫相應的析構函式   

malloc僅僅分配記憶體,free僅僅**記憶體 

假如在定義的結構體中用到了string,string是類,類必須呼叫建構函式才能 生成的,malloc沒有呼叫函式,所以malloc產生的結構體是有問題的,自然就無法賦值了。查c++方面的文獻,看到結構體指標,才想起來new才 是c++的正宗,malloc是c遺留下來的,在物件導向的世界裡malloc明顯不行了。還有內建變數是儲存在棧中的,動態生成的則是放在堆中,不知道 堆中生成的變數能不能賦值給棧中的變數。

在進行c/c++程式設計開發時,經常會遇到malloc/free 與 new/delete 這兩對操作,主要功能就是可以在程式執行過程中動態的申請、釋放記憶體,從而達到對記憶體的操作。但是這兩對操作是有區別的,不能交叉搭配使用:即不能 free掉new來的記憶體,也不能delete掉malloc來的記憶體空間。雖然有時候可以delete掉malloc來的記憶體,或者free掉new來 的記憶體,但是通常情況下會給程式帶來不可預知的錯誤,相信這不是程式設計人員所希望看到的。要養成乙個良好的習慣就是嚴格的配對使用:只用free來釋放 malloc的記憶體空間、只用delete來釋放new來的記憶體空間。

這兩對操作的區別:

1、malloc/free是c/c++中的方法(函式),new/delete是c++中的操作符。

2、malloc申請的是heap區的記憶體空間,而new則是申請的free store區的記憶體空間。

3、使用free之前要判斷,使其free的指標是!null的,使用delete則無須判斷。

4、free掉的記憶體是該指標指向的一段記憶體空間,裡面應該是空的。而delete掉的記憶體是裡面確實存有

資料或者物件的。

5、一下舉例說明其區別:

malloc和free(及其變體)會產生問題的原因在於它們太簡單:他們不知道建構函式和析構函式。

假設用兩種方法給乙個包含10個string物件的陣列分配空間,乙個用malloc,另乙個用new:

string *stringarray1 =

static_cast(malloc(10 * sizeof(string)));

string *stringarray2 = new string[10];

其 結果是,stringarray1確實指向的是可以容納10個string物件的足夠空間,但記憶體裡並沒有建立這些物件。而且,如果你不從這種晦澀的語法 怪圈(詳見條款m4和m8的描述)裡跳出來的話,你沒有辦法來初始化陣列裡的物件。換句話說,stringarray1其實一點用也沒有。相 反,stringarray2指向的是乙個包含10個完全構造好的string物件的陣列,每個物件可以在任何讀取string的操作裡安全使用。

假設你想了個怪招對stringarray1陣列裡的物件進行了初始化,那麼在你後面的程式裡你一定會這麼做:

free(stringarray1);

delete stringarray2;// 參見條款5:這裡為什麼要加上個""

調 用free將會釋放stringarray1指向的記憶體,但記憶體裡的string物件不會呼叫析構函式。如果string物件象一般情況那樣,自己已經分 配了記憶體,那這些記憶體將會全部丟失。相反,當對stringarray2呼叫delete時,陣列裡的每個物件都會在記憶體釋放前呼叫析構函式。

把 new和delete與malloc和free混在一起用也是個壞想法。對乙個用new獲取來的指標呼叫free,或者對乙個用malloc獲取來的指標 呼叫delete,其後果是不可**的。大家都知道「不可**」的意思:它可能在開發階段工作良好,在測試階段工作良好,但也可能會最後在你最重要的客戶 的臉上**。

new/delete和malloc/free的不相容性常常會導致一些嚴重的複雜性問題。舉個例子,裡通常有個strdup函式,它得到乙個char*字串然後返回其拷貝:

char * strdup(const char *ps); // 返回ps所指的拷貝

在 有些地方,c和c++用的是同乙個strdup版本,所以函式內部是用malloc分配記憶體。這樣的話,一些不知情的c++程式設計師會在呼叫strdup後 忽視了必須對strdup返回的指標進行free操作。為了防止這一情況,有些地方會專門為c++重寫strdup,並在函式內部呼叫了new,這就要求 其呼叫者記得最後用delete。你可以想象,這會導致多麼嚴重的移植性問題,因為**中strdup以不同的形式在不同的地方之間顛來倒去。

c++ 程式設計師和c程式設計師一樣對**重用十分感興趣。大家都知道,有大量基於malloc和free寫成的**構成的c庫都非常值得重用。在利用這些庫時,最好是 你不用負責去free掉由庫自己malloc的記憶體,並且/或者,你不用去malloc庫自己會free掉的記憶體,這樣就太好了。其實,在c++程式裡使 用malloc和free沒有錯,只要保證用malloc得到的指標用free,或者用new得到的指標最後用delete來操作就可以了。千萬別馬虎地 把new和free或malloc和delete混起來用,那只會自找麻煩。

malloc函式的實質體現在

它有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足 使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳 給使用者,並將剩下的那塊(如果有的話)返回到連線表上。呼叫free函式時,它將使用者釋放的記憶體塊連線到空閒鏈上。到最後,空閒鏈會被切成很多的小記憶體片 段,如果這時使用者申請乙個大的記憶體片段,那麼空閒鏈上可能沒有可以滿足使用者要求的片段了。於是,malloc函式請求延時,並開始在空閒鏈上翻箱倒櫃地檢 查各記憶體片段,對它們進行整理,將相鄰的小空閒塊合併成較大的記憶體塊。如果無法獲得符合要求的記憶體塊,malloc函式會返回null指標,因此在呼叫 malloc動態申請記憶體塊時,一定要進行返回值的判斷。

new與malloc的區別

1,malloc與free是c c語言的標準庫函式,new delete是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。2,對於非內部資料型別的物件而言,光用maloc free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc f...

new與malloc的區別

malloc 與free 是c c 語言的標準庫函式,new delete 是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。對於非內部資料型別的物件而言,光用maloc free 無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於 malloc...

Malloc與new 的區別

malloc與new 的區別 1,malloc與free是c c語言的標準庫函式,new delete是c 的運算子。它們都可用於申請動態記憶體和釋放記憶體。2,對於非內部資料型別的物件而言,光用maloc free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行...