VC++ 6.0 Debug 版程式若頻繁呼叫 new 或 malloc,運行 4-5 小時後會崩潰,錯誤碼 0x80000003 (Breakpoint),堆疊指向 _heap_alloc_dbg 內的 _CrtDbgBreak()。Release 版與 VS.NET 以上版本不受影響。
CRT Debug Heap 內部維護一個 static long _lRequestCurr 計數器 (初始 1),每次配置記憶體遞增。當計數器從 2,147,483,647 (LONG_MAX) 溢位變為 -2,147,483,648 (LONG_MIN),並持續遞增至 -1 時,恰好等於全域變數 _crtBreakAlloc (預設 -1),觸發 _CrtDbgBreak() 中斷程式。
相關原始碼片段 (dbgheap.c):
long lRequest = _lRequestCurr++; // 每次配置遞增
if (lRequest == _crtBreakAlloc) // _crtBreakAlloc 預設 -1
_CrtDbgBreak(); // 觸發中斷
將 _crtBreakAlloc 設定為極大或極小值,使其永遠不等於 _lRequestCurr。在程式啟動早期 (如 CWinApp::InitInstance) 執行:
#include <limits.h>
long lRequest;
_CrtIsMemoryBlock(malloc(10), 10, &lRequest, NULL, NULL); // 取得目前計數器值
free(...);
long NewCrtBreakAlloc = (lRequest > -1) ? (LONG_MIN / 2) : (LONG_MAX / 2);
_CrtSetBreakAlloc(NewCrtBreakAlloc);
此法確保 _crtBreakAlloc 與遞增計數器永不相遇,徹底解決長時間運行崩潰問題。