首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言記憶體管理陷阱:malloc/free/realloc 正確用法深度解析

     編輯:關於C語言

核心誤區:free() 的參數必須是 malloc/calloc/realloc 的原始回傳值

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 重新分配機制深度解析

realloc(ptr, new_size) 並非總是分配新記憶體並複製:

  • 縮小 (new_size <= old_size):通常就地縮減,回傳原指標,多餘空間標記為可用。
  • 擴大:若原塊後方有足夠連續空閒空間,就地擴展;否則分配新塊、複製資料、釋放舊塊,回傳新位址。
  • ptr 為 NULL:等同 malloc(new_size)。
  • new_size 為 0:實作定義行為 (通常等同 free(ptr) 並回傳 NULL 或唯一指標)。

比喻:家庭財務重新分配

總收入 6000 元,給兒子 1000 元零用錢。重新分配時,不是另開新帳戶,而是在原 1000 元基礎上增減。若減少,多餘部分收回;若增加,嘗試從剩餘家用撥款,不足則另覓資金來源 (新記憶體塊)。

動態記憶體管理五大原則

  1. 需要時分配,用畢即釋:堆疊資源有限,特別是長期運行的服務程式。
  2. 避免大量小塊分配:每次分配有系統開銷 (中繼資料、對齊、鎖競爭);少量大塊優於大量小塊。
  3. 編碼時同步規劃釋放點:寫下 malloc 時,腦中即應有對應 free 的位置與條件。
  4. 迴圈中分配極度謹慎:迴圈內 malloc 必須配對 free,否則指數級洩漏。
  5. 釋放前確保指標未被覆寫: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 指標永遠檢查回傳值
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved