C 標準(C99 §7.20.3.2)明確規定:
free(NULL)是合法的,且不產生任何效果(no operation)。
if (ptr) free(ptr);?| 原因 | 說明 |
|---|---|
| 防禦性編程習慣 | 早期某些非標準庫實現對 free(NULL) 有缺陷,歷史包袱延續至今。 |
| 靜態分析/編譯器警告 | 部分工具(如 MISRA C、Coverity)建議顯式判空,降低誤報。 |
| 代碼可讀性 | 明確表達「僅在指針有效時釋放」的意圖,便於審閱。 |
| 避免雙重釋放邏輯錯誤 | 配合 ptr = NULL; 形成 if (ptr) { free(ptr); ptr = NULL; } 慣用模式,防止二次釋放崩潰。 |
// 模式 1:標準庫保證安全,直接調用
free(ptr);
ptr = NULL; // 防野指針
// 模式 2:宏封裝(推薦用於項目統一風格)
#define SAFE_FREE(p) do { if (p) { free(p); (p) = NULL; } } while(0)
SAFE_FREE(ptr);
free(&local_var) → 未定義行為,通常導致崩潰或堆損壞。free(p); free(p); → 雙重釋放,破壞分配器元數據。free(p); *p = 10; → 野指針寫入,極難復現。malloc/calloc/realloc 以外的指針:如 new 分配需用 delete,混用導致未定義行為。glibc 的 MALLOC_CHECK_=3 環境變量,運行時檢測雙重釋放、越界等。-fsanitize=address) 編譯,自動捕獲 use-after-free、double-free。--tool=memcheck 進行堆分析。free(NULL) 安全無副作用,現代項目可直接調用;但為了防禦性編程、靜態分析通過及團隊風格統一,封裝 SAFE_FREE 宏並統一使用是工程級最佳實踐。