內存動態分配與釋放


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是動態分配內存的運算符,自動計算需要分配的空間,在分配類類型的內存空間時,同時調用類的構造函數對內存空間進行初始化,即完成類的初始化工作。動態分配內置類型是否自動初始化取決於變量定義的位置,在函數體外定義的變量都初始化為0,在函數體內定義的內置類型變量都不進行初始化。

(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++程序的內存分配介紹

該部分參考於http://blog.csdn.net/sparkliang/archive/2008/12/30/3650324.aspx

 

1)棧內存分配運算內置於處理器的指令集中,一般使用寄存器來存取,效率很高,但是分配的內存容量有限。一般局部變量和函數參數的暫時存放位置。

2)堆內存,亦稱動態內存。如mallocnew申請的內存空間。動態內存的生存期由程序員自己決定,使用非常靈活。

3)全局代碼區:從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。

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

5)代碼區:存放整個程序的代碼,因為存儲是數據和代碼分開存儲的。

 

總結:

(1)new、delete 是操作符,只能在C++中使用。malloc、free是函數,可以覆蓋,C、C++中都可以使用。
(2)new 自動計算需要分配的空間大小,可以調用對象的構造函數,對應的delete調用相應的析構函數。malloc僅僅分配內存,free僅僅回收內存,並不執行構造和析構函數
(3)new 類型安全、返回的是某種數據類型指針,malloc 非類型安全、返回的是void指針。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM