1. 程式人生 > >New/delete與malloc/free的詳解

New/delete與malloc/free的詳解

 new/delete與malloc/free的詳解
作者:華清遠見武漢華嵌技術支援曹偉東

內容清單:

1.  C語言中的函式mallocfree

2.  C++中的運算子newdelete

3.  new/deletemalloc/free之間的聯絡和區別

4.  C/C++程式的記憶體分配介紹

具體介紹:

1.   C語言的函式mallocfree

 (1) 函式mallocfree在標頭檔案<stdlib.h>中的原型及引數

void * malloc(size_t size)

動態配置記憶體,大小有size決定,返回值成功時為任意型別指標,失敗時為NULL

              void  free(void *ptr)

釋放動態申請的記憶體空間,呼叫free()ptr所指向的記憶體空間被收回,如果ptr指向未知地方或者指向的空間已被收回,則會發生不可預知的錯誤,如果ptrNULLfree不會有任何作用。

(2) C語言中典型用法

        T為任意資料型別

       T *p = ( T * )malloc( sizeof(T) * n)

       if(NULL= =p)

{

       printf(“malloc fail!\n”);

       ……//相關資源收回的處理

       exit(-1);

}

… …//此過程不能改變指標p的指向

free(p);

注意:malloc

後通常要對返回值進行判斷,避免發生不必要的錯誤。

(3) 記憶體說明

malloc函式動態申請的記憶體空間是在(而一般區域性變數存於棧裡),並且該段記憶體不會被初始化,與全域性變數不一樣,如果不採用手動free()加以釋放,則該段記憶體一直存在,直到程式退出才被系統,所以為了合理使用記憶體,在不適用該段記憶體時,應該呼叫free()。另外,如果在一個函式裡面使用過malloc,最好要配對使用free,否則容易造成記憶體洩露。

2.  C++中的運算子newdelete

newdeleteC++中的運算子,不是庫函式,不需要庫的支援,同時,他們是封裝好的過載運算子,並且可以再次進行過載。

(1)         new是動態分配記憶體的運算子,自動計算需要分配的空間,在C++中,它屬於過載運算子,可以對多種資料型別形式進行分配記憶體空間,比如int型、char型、結構體型和類等的動態申請的記憶體分配,分配類的記憶體空間時,同時呼叫類的建構函式,對記憶體空間進行初始化,即完成類的初始化工作。

(2)         delete是撤銷動態申請的記憶體運算子。deletenew通常配對使用,與new的功能相反,可以對多種資料型別形式的記憶體進行撤銷,包括類,撤銷類的記憶體空間時,它要呼叫其解構函式,完成相應的清理工作,收回相應的記憶體資源。

(3)         典型用法

int *p = new int                       delete p

char *p = new char                  delete p

類的型別 *p = new 類的型別; delete p

//注意,指標p存於棧中,p所指向的記憶體空間卻是在堆中。

                            Obj * p = new Obj[100];                     delete [ ]p;

//注意,new申請陣列,delete刪除的形式需要加括號“[ ]”,表示對陣列空間的操作,總之,申請形式如何,釋放的形式就如何。

(4)         記憶體說明。new申請的記憶體也是存於中,所以在不需要使用時,需要delete手動收回。

3.  new/deletemalloc/free之間的聯絡和區別

(1)          malloc/freenew/delete的聯絡

a)          儲存方式相同。mallocnew動態申請的記憶體都位於堆中。申請的記憶體都不能自動被作業系統收回,都需要配套的freedelete來釋放。

b)          除了帶有建構函式和解構函式的類等資料型別以外,對於一般資料型別,如intchar等等,兩組動態申請的方式可以通用,作用效果一樣,只是形式不一樣。

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

d)          兩組都需要配對使用,mallocfreenewdelete,注意,這不僅僅是習慣問題,如果不配對使用,容易造成記憶體洩露。同時,在C++中,兩組之間不能混著用,雖說有時能編譯過,但容易存在較大的隱患。

(2)          malloc/freenew/delete的區別

a)          mallocfree返回void型別指標,newdelete直接帶具體型別的指標。

b)          mallocfree屬於C語言中的函式,需要庫的支援,而new/deleteC++中的運算子,況且可以過載,所以new/delete的執行效率高些。C++中為了兼用C語法,所以保留mallocfree的使用,但建議儘量使用newdelete

c)          C++中, new是型別安全的,而malloc不是。例如:

int* p = new char[10];                    // 編譯時指出錯誤

  delete [ ]p;                                     //對陣列需要加中括號“[ ]

int* p = malloc(sizeof(char )*10);    // 編譯時無法指出錯誤

   free (p);                                       //只需要所釋放記憶體的頭指標

d)          使用new動態申請類物件的記憶體空間時,類物件的構建要呼叫建構函式,相當於對記憶體空間進行了初始化。而malloc動態申請的類物件的記憶體空間時,不會初始化,也就是說申請的記憶體空間無法使用,因為類的初始化是由建構函式完成的。deletefree的意義分別於newmalloc相反。

e)          不能用mallocfree來完成類物件的動態建立和刪除。

4.  C/C++程式的記憶體分配介紹

1)棧記憶體分配運算內置於處理器的指令集中,一般使用暫存器來存取,效率很高,但是分配的記憶體容量有限。一般區域性變數和函式引數的暫時存放位置。

2)堆記憶體,亦稱動態記憶體。如mallocnew申請的記憶體空間。動態記憶體的生存期由程式設計師自己決定,使用非常靈活。

3)全域性程式碼區:從靜態儲存區域分配。記憶體在程式編譯的時候就已經分配好,這塊記憶體在程式的整個執行期間都存在。例如全域性變數,static變數。

4)常量區:文字常量分配在文字常量區,程式結束後由系統釋放。

5)程式碼區:存放整個程式的程式碼,因為儲存是資料和程式碼分開儲存的。

文章內容說明:由於筆者水平有限,難免有錯誤之處,歡迎廣大網友批評指證。