VC6 DEBUG版下内存控制的一个BUG,导致debug版程序必将崩溃

    最近写的转换程序,在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 ;这一句。不相信的可以自己跑跑试试。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值