程序中出现的堆释放问题

      今天在调试运行时出现这个问题,弹出对话框:user breakpoint called from code at 0x7c92120e,在网上查了一下,发现这可能与堆的分配与释放有关系。参考的有关资料(http://blog.csdn.net/charles_3081523/archive/2010/11/09/5998014.aspx, http://blog.vckbase.com/hyj/archive/2006/06/28/21006.html  )是这样说的:

      这个问题看起来并没有那么严重,不在调试状态下,程序正常运行,即使在调试状态下我们把这个对话框按了确定后,再继续F5,好像什么事情也没有发生,程序仍然在正常运行!隐患!千万不要忽视她!这个信息告诉我们,程序中某个地方已经开始溃烂,如果你频繁的碰到这个对话框,就说明溃烂已经扩大了。为什么会有这样的信息消息框出现呢?这是因为如果我们在调试状态下,操作系统用DebugWin32Heap来替代正常的heap分配内存空间。在这个堆上的任何操作,debug的堆管理器会检查堆的数据完整性,如果它发现了一个错误,就会报告一个消息上来。

      看来问题出在: 在动态分配与释放内存的过程中,堆数据的完整性遭到破坏。这就是可能出现的问题,但是整个程序在堆上分配了那么多对象,到底是哪次出现了问题呢?(接下来就是精确定位出到底哪次内存的分配与释放时出了问题。)可以使用BoundsChecker或PageHeap来精确定位错误发生的位置,但是在网上也没有找到这两个应用程序的可用版,非常沮丧啊!

 

 

      另外,今天无意发现VC自带的可以查看应用程序使用动态链接库的情况的小工具Dependency Walker,个人觉得,根据弹出对话框的代码位置,定位出是使用NTDLL这个动态链接库的RtlLeaveCriticalSection函数时时发生了错误,上网一搜,NTDLL里包含了实现堆释放的功能,RtlLeaveCriticalSection函数是用来释放已经获得的临界区,它的入口点就是0x7c92120e。这又进一步印证了问题确实出在堆释放上。

     堆破坏:堆破坏是应用程序开发的一个常见问题,当应用程序分配一个指定大小的堆内存块,然后又写入了指定堆大小之外的内存地址,就会发生堆破坏。除此之外,当应用程序对应经释放的内存块进行写入操作时,也会发生堆破坏。

 

 

     首先待确定方位,再通过设断点+单步测试,发现当执行到CAppnameView.cpp文件中的pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);语句时,弹出对话框:user breakpoint called from code at 0x7c92120e。

    程序中这句的上下行是这样的:CMainFrame* pFrame = (CMainFrame *)(AfxGetApp()->m_pMainWnd);
                                              pFrame->SendMessage(WM_COMMAND, ID_FILE_NEW);

 

在系统的DLL中AfxGetApp()和m_pMainWnd分别是这样定义的:CWinApp* AFXAPI AfxGetApp();(CWinApp*是返回类型,AFXAPI是函数调用方式,AfxGetApp()是不带参数的函数);CWnd* m_pMainWnd,是CWinThread类的公有成员变量。

是不是强制类型转换出了问题?

 

http://xunwap.net/archives/server-development/cplusplus/动态内存与堆的关系.html,该文中说从一个堆上分配的内存一定要释放到同一个堆上,否则会引起系统的崩溃。这一点在使用基于动态链接库的应用中尤为重要,很可能出现在主程序中分配的内存,在动态链接库中使用,再内存在动态链接库中被释放。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值