動態記憶體管理

realloc(重新配置)

/ REE-alock /

假設你配置了一個容納 10 個項目的緩衝區、填滿了它,現在卻發現需要容納 20 個的空間。你不想丟掉已經有的那 10 個。realloc 就是調整既有配置大小的函式——把它變大(或變小),同時保留裝得下的內容。這名字是 reallocate(重新配置)。

精確地說:realloc(p, newsize) 接受一個你先前由 malloc/calloc/realloc 取得的指標 p,與一個新的位元組大小,回傳一個指向 newsize 位元組區塊的指標,其中保有舊資料的副本(最多到舊、新大小中較小者)。它可能以兩種方式之一達成,而關鍵是你無法選擇:若原地有空間能延展區塊,它回傳同一個位址;否則它在別處配置一塊全新的、較大的區塊,把你的資料複製進去,釋放舊區塊,再回傳新位址。所以舊指標 p 可能變得無效。正確的模式是先把結果指派給一個暫時變數,因為 realloc 也可能失敗回傳 NULL 而原始區塊仍完好——若你寫 p = realloc(p, n) 而它失敗了,你就會用 NULL 覆寫 p 並洩漏原始區塊。變大時新增的位元組未初始化,和 malloc 一樣。

realloc 是可成長陣列(動態陣列,有時稱為 vector)背後的引擎。常見策略是每次填滿就把容量加倍,使附加的平均成本維持很小。兩個邊界情況:realloc(NULL, n) 的行為與 malloc(n) 完全相同;realloc(p, 0) 是請求釋放該區塊(在現代 C 中其確切行為是實作定義,故釋放時請優先用 free)。每次成功的 realloc 之後,你仍然剛好擁有一個活的區塊,最終必須釋放它。

int *tmp = realloc(arr, newcap * sizeof *arr); if (tmp == NULL) { /* 此時 arr 仍然有效 */ free(arr); return -1; } arr = tmp; /* 唯有此時覆寫 arr 才安全 */

先指派給暫時變數:若 realloc 失敗會回傳 NULL 但舊區塊仍存活,所以 p = realloc(p, n) 會洩漏它。

成功的 realloc 之後,任何指向舊區塊的其他指標都成了懸置指標——區塊可能已移動。請從回傳的位址重新取得所有指標。

又称
reallocateresize allocation重新配置