動態記憶體分配

2021-07-24 20:09:22 字數 1733 閱讀 8839

首先是乙個無關的小問題(記個小筆記):包含標頭檔案時""和<>的區別?

答:<>和""表示編譯器在搜尋標頭檔案時的順序不同,<>表示從系統目錄下開始搜尋,然後再搜尋path環境變數所列出的目錄,不搜尋當前目錄,""是表示從當前目錄開始搜尋,然後是系統目錄和path環境變數所列出的目錄。所以,系統標頭檔案一般用<>,使用者自己定義的則可以使用"",加快搜尋速度。

下面進入正題:為什麼使用動態分配記憶體?

陣列的元素儲存於記憶體中連續的位置上。當乙個陣列被宣告時,它所需要的內存在編譯時就被分配。

當你宣告陣列時,你必須用乙個常量指定陣列的長度。但是陣列的長度常常在執行時才知道,這是由於它所需要的記憶體空間取決於輸入資料。例如,乙個用於計算學生等級和平均分的程式可能需要儲存乙個班級的所有學生的資料,但不同班級的學生的數量可能不同。在這種情況下,我們通常的做法是宣告乙個較大的陣列,它可以容納可能出現的最多元素。這種做法應該是我們能想到的最直接辦法,優點是很簡單,但它也有缺點,宣告陣列的長度過大,而實際的元素數量很少,因此,造成大部分記憶體空間的浪費。

c函式庫提供了兩個函式,malloc和free,分別用於執行動態記憶體的分配。

#include

void *malloc(size_t size);

void free(void *pointer);

malloc返回乙個型別為void*的指標,這個指標指向被分配的記憶體塊起始位置,因此可以強制轉換為其他任何型別的指標。

free的引數要麼是null,要麼是乙個先前從malloc、calloc、realloc返回的值。向free傳遞乙個null引數不會產生任何效果。

malloc的引數就是需要分配的記憶體位元組數。如果記憶體池中的可用記憶體可以滿足這個需求,malloc就返回乙個指向被分配的記憶體塊起始位置的指標。

malloc所分配的是一塊連續的記憶體。同時,malloc實際分配的記憶體有可能比你請求的稍微多一點,這個行為是由編譯器定義的。對於要求邊界對齊的器,malloc所返回的記憶體的起始位置將始終能夠滿足對邊界對齊要求最嚴格的型別的要求。

如果作業系統無法向malloc提供更多的記憶體(記憶體池為空或者它的可用記憶體無法滿足你的要求),malloc就返回乙個null指標。因此,對每個從malloc返回的指標都進行檢查,確保它並非null是非常重要的。

#include #include #define size 20

int main(void)

else

else

else

else

{for(i=0; i

從結果中可以驗證上述理論:

(1)如果用它擴大乙個已經分配好的記憶體塊,那麼這個記憶體塊的原先內容依然保留,新增加的記憶體新增到原先記憶體的後面,但新記憶體此時並未進行初始化;

(2)如果用它縮小乙個已經分配好的記憶體塊,該記憶體塊的尾部部分便被拿掉,剩餘部分記憶體內容依然保留。

★常見的動態記憶體錯誤

:(1)對null指標進行解引用操作;

(2)對分配的記憶體進行操作時越界;

(3)釋放並非動態分配的記憶體;

(4)試圖釋放一塊動態分配的記憶體的一部分:動態分配的記憶體必須整塊一起釋放。但是,realloc函式可以縮小一塊動態分配的記憶體,有效地釋放它尾部的部分記憶體;

(5)一塊動態記憶體被釋放之後被繼續使用

(6)記憶體洩漏:分配記憶體但在使用完畢後未釋放,引起記憶體洩漏,記憶體洩漏會增加程式的體積,有可能導致程式或系統的崩潰。

動態記憶體分配

在c 中建立乙個物件時,我們必須要為這個物件申請一塊記憶體,而且要用建構函式對這塊記憶體進行初始化。c 中的new和delete相對於c的庫函式malloc和free在這方面有很大的優勢,所以我們主要講的是運算子new和delete。當用new來建立乙個物件時,它會自動在堆裡為物件分配記憶體並且為這...

動態記憶體分配

為什麼使用動態記憶體分配?c語言中的一切操作都是基於記憶體的 變數和陣列都是記憶體的別名,如何分配這些記憶體由編譯器在編譯期間決定 定義陣列的時候必須指定陣列唱的 而陣列長度是在編譯期就必須決定的 需求 程式執行的過程中,可能需要使用一些額外的記憶體空間 malloc和free malloc和fre...

動態記憶體分配

c的儲存類別有4種 自動的 auto 靜態的 statics 暫存器的 register 外部的 extern 全域性變數時分配在記憶體中的靜態儲存區 靜態區域性變數屬於靜態儲存類別,在靜態儲存區內分配儲存單元,是在編譯時賦初值的,只賦初值一次,在程式執行時它已有初值,以後每次呼叫函式時不再重新賦初...