void *p = malloc(sizeof(double) * 6);
double *dp = (double *)malloc(sizeof(double) * 6);
// 錯誤:free(dp) 若 dp 非原始回傳值 (如經過位移運算) 會導致未定義行為
// 正確:free(p) 或 free(dp) 僅當 dp 保存原始位址時
// 危險範例
p = dp; // p 現在指向 dp 的原始位址
free(p); // 正確
// 但若
dp++; // dp 位移後不再是原始位址
free(dp); // 嚴重錯誤:heap corruption
for (;;) {
double *p = malloc(sizeof(double) * 6);
free(p); // 若漏掉 free,記憶體將耗盡
}
觀察系統記憶體使用量,若持續上升表示 free 未正確釋放 (或雙重釋放導致 heap 損壞)。
realloc(ptr, new_size) 並非總是分配新記憶體並複製:
new_size <= old_size):通常就地縮減,回傳原指標,多餘空間標記為可用。malloc(new_size)。free(ptr) 並回傳 NULL 或唯一指標)。總收入 6000 元,給兒子 1000 元零用錢。重新分配時,不是另開新帳戶,而是在原 1000 元基礎上增減。若減少,多餘部分收回;若增加,嘗試從剩餘家用撥款,不足則另覓資金來源 (新記憶體塊)。
malloc 時,腦中即應有對應 free 的位置與條件。malloc 必須配對 free,否則指數級洩漏。ptr = other_ptr; free(ptr); 導致原記憶體無法釋放 (洩漏)。| 錯誤代碼 | 後果 | 修正 |
|---|---|---|
free(ptr+1) | Heap corruption, crash | 保存原始指標 |
ptr = realloc(ptr, sz); if(!ptr) free(old); | realloc 失敗時 old 仍有效,但此處已丟失 | 用暫存變數接收 realloc 回傳值 |
free(ptr); free(ptr); | Double free, heap corruption | 釋放後置 NULL: free(ptr); ptr=NULL; |
malloc 未檢查 NULL | 解參考 NULL 指標 | 永遠檢查回傳值 |