記憶體與指標

堆積

堆疊很適合「生命期與函式呼叫相符」的記憶體,但有時你需要的記憶體必須活得比建立它的函式更久,或其大小要到執行期才知道。堆積(heap)就是程式定址空間中為此保留的區域:你明確要求的記憶體,會一直留著,直到你明確把它還回去。

與堆疊不同,堆積不綁定呼叫與返回。你用一個配置呼叫要一塊記憶體,拿回一個指向它的指標,而那塊記憶體會持續存在——跨越函式返回、想留多久就多久——直到你釋放它。堆積按需要成長(經典上向上、朝較高位址,與堆疊相反),執行期的配置器從中切出你要求的區塊,並追蹤哪些部分正在使用。因為沒有東西會自動回收堆積記憶體,所有權就成了你必須回答的問題:總得有人記得把每塊記憶體「恰好釋放一次」。下一個領域「動態記憶體」整個就在談這個區域;在這裡,知道它是什麼、以及它和堆疊有何不同就夠了。

兩個誠實的提醒。第一,和呼叫堆疊一樣,這裡的「堆積」是用於動態配置的記憶體區域——它不是堆積資料結構(優先佇列那棵樹);它們同名只是巧合。第二,堆積記憶體靈活但並非沒有代價:配置與釋放都要真正的工作,區塊若忘了釋放會洩漏,而被釋放的區塊會讓你的指標懸置。堆疊自動又快;堆積手動又靈活——在兩者間取捨是一再出現的設計決策。

char *p = malloc(256); 在堆積上滿足「要 256 個位元組」的請求並回傳指向它的指標;那塊記憶體存活到當前函式之後,只有 free(p) 才回收它。忘了 free(p) 就洩漏了那 256 個位元組。

堆積區塊持續存在直到明確釋放——所有權是你的工作。

「堆積」(用於動態配置的記憶體區域)不是堆積資料結構(優先佇列那棵樹)——名字只是碰巧相同。在 C 裡堆積記憶體永遠不會自動回收,所以每塊都需要一個負責「恰好釋放一次」的所有者;細節(malloc、free、洩漏、釋放後使用)屬於 e 領域。

又称
dynamic memory regionfree store堆積