【補充】new 和 malloc 的區別

 

 

 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管理動態內存;

5、 new能夠認爲是malloc加構造函數的執行。new出來的指針是直接帶類型信息的。而malloc返回的都是void指針。

6、 內存泄漏對於malloc或者new均可以檢查出來的,區別在於new能夠指明是那個文件的那一行,而malloc沒有這些信息。

7new 和 malloc效率比較: 

    new 有三個字母, malloc有六個字母 

    new能夠認爲是malloc加構造函數的執行。
 new出來的指針是直接帶類型信息的, 而malloc返回的都是void指針。 8new是保留字,不須要頭文件支持;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<string*>(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能夠這麼有效地與構造函數和析構函數交互,選用它們是顯然的。

把new和delete與malloc和free混在一塊兒用也是個壞想法。對一個用new獲取來的指針調用free,或者對一個用malloc獲取來的指針調用delete,其後果是不可預測的。你們都知道「不可預測」的意思:它可能在開發階段工做良好,在測試階段工做良好,但也可能會最後在你最重要的客戶的臉上爆炸。

new/delete和malloc/free的不兼容性經常會致使一些嚴重的複雜性問題。舉個例子,<string.h>裏一般有個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和free對構造函數和析構函數一無所知,把malloc/free和new/delete混起來用又象嘈雜擁擠的晚會那樣難以控制,那麼,你最好就何時都一心一意地使用new和delete吧
相關文章
相關標籤/搜索