動態內存簡介

爲什麼要使用動態內存?

通常當我們聲明一個數組時必須要指定數組的長度,但是數組的長度只有在程序運行的時候才知道,這是因爲它所需的內存空間取決於輸入數據的類型。這種方法雖然簡單,但是它的缺點也是顯而易見的,它極大的限制了程序的靈活性和健壯性。這種方式受到了人爲的限制,一旦我們輸入的數據元素超過了數組長度,它就無法處理這種情況,所以通常我們將數組的長度設置的很大,但是問題又來了,如果數組很大,我們輸入的數據元素又很少,這樣就極大地浪費了內存空間。更重要的一個問題是如果我們輸入的元素超過了數組長度,有些編譯器是不會報錯的,它會把數組存滿,剩餘的元素不再存取,這樣就使得程序輸出一個錯誤的值,所以我們有的時候需要使用動態內存。

“動態內存分配”主要是爲了解決那些在運行時才知道所需內存空間的數組的內存分配。

首先我們先來了解malloc、calloc、realloc、free這四個函數:

void *malloc(size_t size);

參數size:所需空間的字節個數

malloc實現內存的分配,當程序調用malloc時,malloc從內存池中提取出一塊合適的且地址連續的內存(沒有初始化),並把內存的首地址返回,但是malloc並不知道我們申請的是int類型還是float類型或者其他類型,所以malloc函數返回的是一個void*,可以轉換成任何類型的指針,我們接受返回值時要對其進行強制類型轉換。如果內存池中的空間不足,則malloc會返回一個空指針(NULL),所以使用malloc開闢的空間在使用時我們必須檢查其返回值是否爲空。

void *calloc(size_t n,size_t size);

參數n:所申請的元素的個數

參數size:每個元素所佔的字節數

calloc也能實現動態內存的分配,它與malloc有兩個不同的區別,第一使用calloc申請的空間會被初始化爲0(在返回首地址之前),第二是參數不同,calloc需要兩個參數,一個是元素的個數,一個是每個元素所佔的字節數。

void *realloc(void* ptr,size_t newsize);

參數ptr:原內存的地址

參數newsize:連同舊內存一起,所需要的總內存大小

realloc用於修改一個已經分配好內存的內存塊的大小,使用realloc這個函數可以使得原內存擴大或者縮小。

擴大內存:那麼它會保留原內存的內容,並在原內存的後面開闢要增加的字節的空間,而不對新增加的內存進行初始化。如果原內存塊後面的空間小於新增字節的大小,則realloc會在內存中重新找一塊滿足要求的空間,把原內存的內容複製過去,並返回新內存的地址,所以使用realloc後就不能使用舊內存的地址了,而應該使用新內存的地址。

縮小內存:realloc會將原內存尾部的部分內存釋放掉。

如果realloc返回NULL就與malloc一樣。

free(p);

free的參數必須是NULL,或者是malloc、calloc、realloc的返回值。

它的作用是釋放內存(用完內存後必須釋放,不然會發生內存泄漏,內存越用越少)。當然,當你釋放完空間後p依然指向內存的起始位置,所以還要手動的將地址p賦值爲空,即p = NULL。

使用free時一定要確保不再訪問被釋放內存的地址。

動態內存使用的常見錯誤:

1.沒有檢查內存是否分配成功

2.操作內存時越界

例如:申請一個數組arr[3],如果數組引用時下標小於0或大於2都會發生越界

3.使用free釋放內存後,仍然訪問被釋放內存的地址



發佈了78 篇原創文章 · 獲贊 98 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章