動態記憶體配置(dynamic memory allocation)
想像你正在寫一個程式,但你還不知道資料會變得多大。也許使用者只輸入一行文字,也許輸入一萬行;也許他們載入一張小照片,也許是一張巨大的照片。寫程式的當下你無法知道——只有在程式執行時才會明朗。動態記憶體配置就是 C 程式在執行期向系統索取一塊記憶體的方式,大小依照當下真正的需求而定,而不必事先猜測。
實際運作如下。一個 C 程式本來就免費擁有兩種記憶體:全域變數(大小固定,在程式建構時就決定)與住在堆疊(stack)上的區域變數(隨著函式互相呼叫而自動建立與銷毀)。動態配置是第三種來源。你呼叫像 malloc(n) 這樣的函式,說我需要 n 個位元組。系統會在一塊稱為堆積(heap)的記憶體區域中找到一段這麼大的閒置空間,並回傳一個指標——也就是第一個位元組的位址。這塊記憶體現在歸你所有,可以讀寫,直到你用 free() 明確歸還為止。大小 n 可以是任何在執行期算出的數字;例如 malloc(count * sizeof(int)) 就剛好保留你發現所需的那麼多個整數的空間。
為何重要:這是幾乎所有有趣的資料結構的基礎——會成長的串列、樹、容納未知長度檔案的緩衝區。它也伴隨著責任。在 C 中沒有自動清理:malloc() 給你的記憶體不會自動清空,系統也不會主動釋放它;若你弄丟指標卻沒釋放,那塊記憶體就會被浪費到程式結束為止。這個領域中的其他一切——洩漏、懸置指標、所有權——其實都在談如何小心地駕馭這項能力。
int n = how_many_users(); /* 只有執行期才知道 */ int *ids = malloc(n * sizeof(int)); if (ids == NULL) { /* 記憶體不足 */ } /* ... 使用 ids[0] .. ids[n-1] ... */ free(ids);
在程式執行時決定,剛好保留 n 個整數的空間,用完再歸還。
動態不代表慢或神奇——它的意思是大小與時機在執行期決定,而非編譯期。忘記釋放你所配置的記憶體,是 C 中大多數記憶體錯誤的根源。