• HEAP: Free Heap block XXXX modified at XXXX after it was freed 的处理


     HEAP: Free Heap block XXXX modified at XXXX after it was freed 的处理

    环境:Windows XP SP3,VC2008

    在开发过程中,偶尔会遇到程序提示 HEAP异常的情况

    以下讨论限于Debug模式

    常见提示如下

    vc的输出窗口提示:

    翻译过来就是 某个已经释放的堆空间被修改了,就是某块动态申请(malloc/new)的内存,在它被释放(free/delete)后,又被使用了。

    比如编写了如下的代码,就会有这个提示

    以上代码比较简单,可以很容易的看出问题出在哪里,当代码量比较大的时候,就不是一眼就能看出来了。

    在以上代码中,调试器断在了line31,那是一句申请空间的语句,当申请空间的时候,crt会进行一定的检查,所以就发现了这个heap 错误。

    为了查找是哪一个地方的内存错误,需要借助 VC 提供的几个 heap debug 函数。

    在程序的开始部分加入

    它们会把malloc/free函数映射到dbg版的函数上去,那几个函数有调用时的文件名和函数行数信息,方便定位代码位置

    修改后的代码如下

    _CrtSetDbgFlag() 是设置调试标志,这里设置了_CRTDBG_CHECK_ALWAYS_DF(每一次malloc/free等操作,都对内存进行检查) 和 _CRTDBG_DELAY_FREE_MEM_DF(释放free掉的内存还是放在heap list里,方便以后找出这块内存的具体位置)。

    _CrtMemCheckpoint() 设置内存检测点,类似于给当前heap内存做一个快照。快照信息就放在它的参数里面,如memStat里。

    准备工作做完后,再次运行这个程序,heap 错误的提示又再次出现了,下面进行分析

    红色圈起来的地方值得注意,一个是出问题的内存的位置,一个是出问题的内存的大小。

    刚才提到了一个变量memStat,这是一个结构体变量,定义如下:

    pBlockHeader是一个结构体指针,指向内存块链表

    lCounts介绍了各种类型(_FREE_BLOCK、_NORMAL_BLOCK、_CRT_BLOCK、_IGNORE_BLOCK、_CLIENT_BLOCK)的内存块的数量,这些内存块可以通过遍历pBlockHeader指向的链表得到

    其他的这里用不到,就不介绍了,详情参考 MSDN

    _FREE_BLOCK 类型的内存块就是出问题的内存块,通过遍历pBlockHeader就可以找到,pBlockHeader类型定义如下

    由以上定义可以看出来,pBlockHeader指向一个双向链表,其中

    szFileName 是申请空间时的文件名

    nLine 是申请时的代码行号

    nDataSize 是申请的内存大小

    nBlockUse 是内存块类型(_FREE_BLOCK、_NORMAL_BLOCK、_CLIENT_BLOCK等)

    lRequest 是申请次数,查找内存泄漏的时候用的到

    gap/anotherGap 是填充空间,做内存边界用,可用来检测上下溢出

    data 这块就是我们使用的内存了,data的地址和出错时提示的地址是一个内容

    通过定义,可以发现 _CrtMemBlockHeader 的大小是32即0x20,在pBlockHeader里查找错误地址时需要查找 [xxxx – 0x20] 这个地址。

    在这个例子里,就是查找[0x00035C68 – 0x20 = 0x00035C48],在Watch里跟踪pBlockHeader,很快就可以找到这个地址

    红色圈起来的地方就可以找到出问题的 heap 地址了

    对照源代码

    就能发现是哪个地方申请的变量出问题了

    跟踪这个变量,一般很快就能发现问题了

    demo下载:http://download.csdn.net/detail/xkxjy/3869116

     

     

  • 相关阅读:
    详述JavaScript实现继承的几种方式
    理解javascript函数调用和“this”
    React-Native 组件开发方法
    React Native 中 component 生命周期
    React-Native 样式指南
    React Native 之flex布局
    转每天一个linux命令(5):rm 命令
    [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上)
    转每天一个linux命令(4):mkdir命令
    转每天一个linux命令(3):pwd命令
  • 原文地址:https://www.cnblogs.com/xkxjy/p/3672277.html
Copyright © 2020-2023  润新知