_heap_alloc_debug 會使程序崩潰調。所有版本的VC++6.0。
new中調用了._malloc_dbg(), 和_heap_alloc_dbg().
在_heap_alloc_dbg()中有個靜態的long 型計數器, _lRequestCurr (Microsoft visual StudioVC98CrtSrcdbgheap.c),初始化為1。
每次new()或 malloc()調用,這個計數器加1,當你的程序運行到足夠時間,這個值會在 -2,147,483,648 to 2,147,483,647之間。
問題在於如下的代碼 _heap_alloc_dbg():
/* break into debugger at specific memory allocation */
if (lRequest == _crtBreakAlloc)
_CrtDbgBreak();
lRequest 初始化為_lRequestCurr,_crtBreakAlloc 初始化為-1,當程序啟動時。
每次 malloc(), lRequest (_lRequestCurr) 加1,經過一段時間運行後,lRequest (_lRequestCurr) 達到2,147,483,647. 下一次調用加1, 2,147,483,647 + 1 = -2,147,483,648.,下面的調用 lRequest (_lRequestCurr)從-2,147,483,648 加到 -1, _crtBreakAlloc 的值和lRequest (_lRequestCurr) 值都為-1時, _CrtDbgBreak() 調用,然後錯誤出現。
_CrtDbgBreak() 顯示出異常情況,並且停止程序。測試程序在4-5個小時之間崩潰。報出錯誤為:
應用程序發生異常,unknown software exception(0x80000003),位置為0x10212ad0.
所有new().malloc()頻繁調用的程序,在DEBUG版本中早晚都會崩潰。
在新版本的VS.Net中沒有這個問題。
一個解決例子:
#include LIMITS.H
long lRequest;
long NewCrtBreakAlloc;
my_pointer = malloc(10);
_CrtIsMemoryBlock(my_pointer, 10, &lRequest, NULL, NULL);
free(my_pointer);
if (lRequest > -1)
NewCrtBreakAlloc = LONG_MIN / 2;
else
NewCrtBreakAlloc = LONG_MAX / 2;
_CrtSetBreakAlloc(NewCrtBreakAlloc);
這種方式下 lRequest == _crtBreakAlloc永遠不會發生 。
這個BUG的發現解決了我們公司一個大型軟件幾年來的問題。