記憶體區域速覽
- 棧:函式區域變數、參數、返回位址,自動管理;
- 資料段:全域/靜態變數,程式啟動時配置,自動歸零;
- 堆:動態配置區域,由程式設計師手動管理(malloc/free)。
四大核心函式
| 函式 | 原型 | 特性 |
| malloc | void *malloc(size_t size) | 分配 size 位元組,內容未初始化(垃圾值),失敗回傳 NULL |
| calloc | void *calloc(size_t n, size_t sz) | 分配 n*sz 位元組並歸零,適合陣列/結構體初始化 |
| realloc | void *realloc(void *ptr, size_t size) | 調整既有區塊大小;size=0 相當於 free;可能移動記憶體位址 |
| free | void free(void *ptr) | 歸還區塊給堆;ptr 必須來自 malloc 系函式,重複 free 導致崩潰 |
正確使用範例
int *pi = malloc(sizeof(int));
if (!pi) { /* 處理失敗 */ }
*pi = 42;
printf("value=%d, addr=%p\n", *pi, pi);
free(pi); // 歸還記憶體
pi = NULL; // 避免野指標
// calloc 歸零陣列
int *arr = calloc(100, sizeof(int)); // 100 個 0
// realloc 擴容
arr = realloc(arr, 200 * sizeof(int));
if (!arr) { /* 原指標仍有效,需另行處理 */ }
四大經典錯誤與對策
- 記憶體洩漏:malloc 後未 free → 配對使用,或用 RAII/智慧指標(C++);
- 野指標:free 後繼續使用 →
free(ptr); ptr = NULL;
- 重複釋放:兩個指標指向同一區塊 → 明確所有權,或 free 後置 NULL;
- 越界存取:寫入超出配置大小 → 嚴格檢查索引,使用工具。
進階話題
- 記憶體對齊:malloc 回傳位址滿足最大基本型別對齊(通常 8/16 位元組);
- 自定義分配器:嵌入式系統常實作記憶體池避免碎片;
- 垃圾回收:C 標準不支援,但可引入 Boehm GC 或使用 C++ 智慧指標。