C語言基本教程 第10課 動態記憶體分配

2021-07-16 23:14:16 字數 3728 閱讀 1651

之前介紹了 c 程式的記憶體,這裡大概溫習一下:

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

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

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

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

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

今天的主角就是 堆記憶體  的 動態分配與釋放

假設要編寫乙個程式,要對乙個學校的學生進行資料處理, 因為學校的人數是不固定的, 我們不知道硬體建立乙個多大的陣列, 陣列小了,到時候人多了就不夠用,

陣列大了,就是浪費記憶體空間.

若使用動態記憶體分配(dynamic memory allocation),所使用的記憶體就不會比指定的學生分數所需的記憶體多。

可以在執行時建立足以容納所需資料量的陣列。

1.   c語言的函式malloc和free

(1) 函式malloc和free在標頭檔案中的原型及引數

void * malloc(size_t size)

動態配置記憶體,這裡的記憶體就是指 堆記憶體(heap), 大小有size決定,返回值成功時為任意型別指標,失敗時為null。

void  free(void *ptr)

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

(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++中的運算子

new和delete

new和delete是c++中的運算子,不是庫函式,不需要庫的支援,同時,他們是封裝好的運算子。

(1)new是動態分配記憶體的運算子,自動計算需要分配的空間,在分配類型別的記憶體空間時,同時呼叫類的建構函式對記憶體空間進行初始化,即完成類的初始化工作。動態分配內建型別是否自動初始化取決於變數定義的位置,在函式體外定義的變數都初始化為0,在函式體內定義的內建型別變數都不進行初始化。

(2)delete是撤銷動態申請的記憶體運算子。delete與new通常配對使用,與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/delete與malloc/free之間的聯絡和區別

(1)          malloc/free和new/delete的聯絡

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

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

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

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

(2)          malloc/free和new/delete的區別

a)malloc和free返回void型別指標,new和delete直接帶具體型別的指標。

b)malloc和free屬於c語言中的函式,需要庫的支援,而new/delete是c++中的運算子,所以new/delete的執行效率高些。c++中為了兼用c語法,所以保留malloc和free的使用,但建議盡量使用new和delete。

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

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

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

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

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

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

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

總結:

(1)new、delete 是操作符,只能在c++中使用。malloc、free是函式,可以覆蓋,c、c++中都可以使用。

(2)new 自動計算需要分配的空間大小,可以呼叫物件的建構函式,對應的delete呼叫相應的析構函式。malloc僅僅分配記憶體,free僅僅**記憶體,並不執行構造和析構函式

(3)new 型別安全、返回的是某種資料型別指標,malloc 非型別安全、返回的是void指標。

C語言 動態記憶體

動態記憶體 動態的建立記憶體,申請記憶體空間為變數 存放於堆區,不能通過變數名或陣列名引用,只能通過指標引用,在windows中,堆中最大的連續記憶體塊為1.3g左右。標頭檔案 includemalloc 在空閒記憶體中分配連續記憶體,約等於2g,分配成功時返回乙個指向該記憶體塊的指標即第乙個位元組...

c語言動態記憶體分配 C 動態記憶體分配

動態記憶體分配 雖然通過陣列就可以對大量的資料和物件進行有效地管理,但是很多情況下,在程式執行之前,我們並不能確切地知道陣列中會有多少個元素。這種情況下,如果陣列宣告過大,就會造成浪費 宣告過小,就會影響處理。在c 中,動態記憶體分配技術可以保證程式在執行過程中按照需要申請適量記憶體,使用後釋放,從...

iOS C語言10 動態記憶體分配

main.m c10 動態記憶體分配 created by dllo on 15 7 13.import void func char fun 定義乙個全域性變數 int global 10 測試靜態變數只會初始化一次 void test int main int argc,const char a...