大型專案中 malloc/free 崩潰往往難以定位,實際多源於模組邊界記憶體管理不一致。本文歸納四大典型失效模式與架構級解決方案。
void foo() {
int* p; // 未初始化,值隨機
free(p); // 崩潰:傳遞野指標給釋放器
}
鐵律:指標宣告即初始化 int* p = nullptr;,free(nullptr) 安全無害。
int* p = (int*)malloc(100); p++; // 指標偏移 free(p); // 崩潰:傳遞非區塊起始位址
對策:保留原始指標 void* orig = p;,運算用副本,釋放用 orig。
現象:DLL 內 malloc 回傳指標,主程式 free 崩潰。
原因:各模組連結獨立 CRT 堆積(Debug Multithreaded DLL vs Debug Multithreaded),堆積管理結構不共享。
DLL_API void FreeMyBuffer(void* p) { free(p); }free。HeapAlloc(GetProcessHeap(), 0, size) / HeapFree(GetProcessHeap(), 0, p)| 主程式 | DLL | 結果 |
|---|---|---|
| MDd (Debug DLL) | MTd (Debug Static) | free 崩潰、delete 崩潰 |
| MD (Release DLL) | MT (Release Static) | 同上 |
| MDd | MDd | 正常 |
強制規範:專案群組內所有模組 必須 統一 Runtime Library 設定(皆 MDd 或皆 MD)。
std::string/std::vector/std::shared_ptr(同 CRT 版本),或定義 allocate/free 配對介面。malloc 在 DLL,free 在 EXE;new 在 DLL,delete 在 EXE。