動態內存管理是 C 語言核心難點,free 使用不當導致的野指針問題更是無數開發者的噩夢。本文結合 MSDN 規範、代碼演示、管家比喻,系統梳理 free 行為規範、野指針成因與防範策略。
void free(void *ptr); // 需包含 <stdlib.h> 或 <malloc.h>
核心規範:
malloc/calloc/realloc 分配的內存塊,歸還可用池malloc 與 free 次數必須嚴格配對NULL → 安全無操作free 不修改指針本身值,指針仍指向原地址(現為無效內存)野指針 ≠ 空指針。野指針指向「垃圾內存」——已被釋放或未初始化的地址,程序員無法控制其指向內容。
| 成因 | 說明 | 典型代碼 |
|---|---|---|
| 1. 指針未初始化 | 新建指針默認值隨機,非 NULL | int *p; *p = 10; // 崩潰 |
| 2. free/delete 後未置 NULL | 內存歸還,指針懸空,if(p!=NULL) 無法攔截 | free(p); strcpy(p, "x"); // 危險 |
| 3. 指針超出變量作用域 | 返回局部變量地址、訪問已銷毀對象 | int* f(){int a; return &a;} |
char *ptr = (char*)malloc(100);
strcpy(ptr, "Hello");
free(ptr); // 內存歸還系統,ptr 成野指針
if (ptr != NULL) { // 條件成立!ptr 非 NULL 但指向垃圾
strcpy(ptr, " world"); // 寫入已釋放內存 → 未定義行為
printf("%s\n", ptr);
}
正確模式:free(ptr); ptr = NULL; —— 雙重保險,二次 free(NULL) 安全無害。
- CRT 內存管理模塊 = 管家
- 你的程序 = 客人
malloc= 「管家,借 XX 個水桶」free= 「管家,用完了,還你!」- 管家不清洗水桶(不清零內存),直接借給下一位客人
- 你
free後繼續用 = 往別人水桶裡撒尿 → 好管家殺了你(崩潰),壞管家裝不知 → 客戶喝到尿(數據竄改)ptr = NULL= 告訴自己「水桶已還,別再用」
if(!ptr) { perror("malloc"); abort(); }malloc 對應一個 freefree(p); p = NULL; 形成肌肉記憶FILE *fp = fopen("abc", "r+");
if (NULL == fp) {
perror("abc"); // 輸出: abc: No such file or directory
}
perror 根據全局 errno 輸出系統錯誤信息,是調試文件/內存操作失敗的利器。