unknown software exception(0x80000003)

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

    最近寫的轉換程式,在debug版下跑了9個小時,最終崩潰,直接彈出對話方塊說:

    應用程式發生異常,unknown software exception(0x80000003),位置為0x10212ad0.    

   又在IDE狀態下debug版跑了16個小時,最終彈出使用者斷點對話方塊,點按鈕後定位在 DBGHEAP.c 檔案的第338行:

  1. /* break into debugger at specific memory allocation */
  2. if (lRequest == _crtBreakAlloc)
  3.     _CrtDbgBreak(); 

   這段程式碼的作用是在達到指定記憶體分配次數時進行中斷,以便於使用者除錯。這時lRequest == _crtBreakAlloc成立,lRequest =-1,其中,lRequest記錄了當前記憶體分配次數,_crtBreakAlloc為使用者設定的中斷點(通過呼叫_CrtSetBreakAlloc進行設定),其初始值為-1L,即long型整數最大值。

   問題是:即使使用者沒有設定中斷點,那麼隨著程式的執行其記憶體分配次數總會有達到最大值的那一刻。

 

  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(),然後就出現使用者設定斷點提示,非IDE狀態的debug版本則會直接報錯崩潰。

 

   這說明我們的程式存在非常頻繁的記憶體分配,可以考慮使用記憶體池以提高效率。


    解決辦法有兩個:

    1. 改用RELEASE版。事實證明,release版本下不會出現該錯誤。

    2. 少用malloc,new和delete動態分配記憶體;減少string和CString的使用,因為CString在內部實現中會呼叫new實現動態記憶體,想想啊,CString的字串長度是可以任意變的,怎麼會沒有動態記憶體分配,又不可能每個CString都內建4G空間,對吧。(今天有看到帖子說,在debug版本中,cstring使用new和delete實現,但在release版本中小於512位元組時使用4個不同大小的記憶體池實現,大於512位元組時仍使用new和delete)

 

   問題解決過程中參考了兩個blog,向作者致謝:

   1. http://blog.csdn.net/freefalcon/archive/2006/10/26/1352048.aspx

   2. http://blog.csdn.net/sijigang/archive/2007/01/15/1483934.aspx

 

  下面給出一個最簡單的測試用例:

  1. #include <stdio.h> 
  2. int main() 
  3. {  
  4.     int* i;
  5.     unsigned int j = 0;
  6.     while (1)
  7.     {
  8.         i = new int;
  9.         *i = 0;
  10.         j ;
  11.         delete i;
  12.     }
  13.     
  14.     return 1;

  本人今天(2008。12。25 WINXP SP2 VC6 SP6)在debug模式下跑了大概一兩個小時後崩潰。崩潰斷點就在i = new int;這一句。不相信的可以自己跑跑試試。

相關文章

程式語言 最新文章