HEAP: Free Heap block 39rt98 modified at 39rtc0 after it was freed



HEAP: Free Heap block 39rt98 modified at 39rtc0 after it was freed


一. 介绍这个问题之前,先来简要对一些概念进行梳理。

Heap,堆,一种由程序员根据实际需求人为分配、释放的数据存储单元。

通常情况下,通过调用malloc函数,或者 new特殊字符来创建出来。

相对应的是通过调用free函数,或者delete操作符进行人为释放。


与之相对应的是Stack,栈,一种由操作系统控制分配、使用、释放的数据存储单元。


二.  HEAP: Free Heap block 39rt98 modified at 39rtc0 after it was freed

这句话的意思是,释放了内存开始为0x39rt98的堆块后,堆块所在内存的0x39rtc0位置被更改了。

这样就好办了,我们只需要查找到0x39rt9所在位置属于分配给了哪个对象,然后再定位0x39rtc0所处的成员变量

然后查找所有使用该变量并进行了变量内容的修改的代码就可以定位到错误位置了。再根据情况修改代码,避免内存释放后仍然进行修改即可。


三.出现该问题一般就是使用了野指针导致的.

那么何为野指针呢?

野指针与NULL指针不同.所谓野指针是指指针所指的内存已经回收,而继续使用该指针,导致未定义行为.

内存已经被释放了,后面还继续使用。简单点说就是野指针!而造成野指针的原因很简单,就是内存被释放了。

于是,问题变简单了:找出所有释放内存的地方。释放内存的,主要就2个:free和delete.

于是,我定义了3个宏,

SAFE_DEL_PTR(p)           if(p){delete (p); (p)=NULL;}
SAFE_DEL_ARRAY(p)      if(p){delete [] (p); (p)=NULL;}
SAFE_FREE_PTR(p)         if(p){free(p); p=NULL;}

然后把所有用到这两个的地方都用宏替换掉,然后再把这两个宏里面真正释放的给注释掉。再跑,发现很OK,不会崩溃了。 于是,确认了是释放引起的。


四.也有用gflags来处理这类堆释放问题的。

用windows的debug tools中的global flags即gflags就可以了。gflags工作的时候,可以在用户每次分配内存的时候都在要分配的内存后边紧跟着分配一个保护区间(一般是一个虚拟页),一旦出现堆越界,就会立刻触发中断,这样就可以让调试器准确的定位代码行。

这里所说的立刻触发中断并不是必然的,取决于gflags的设置参数,如果启用了/unaligned参数,则会以不对齐的方式分配保护区间,这样即使越界一个字节都会立即触发异常;默认情况下分配保护区间是以对齐内存为单位的,因此在下面这种越界情况是检测不到的:

    int main()  
    {  
          char *p = new char[10];  
          for(int i=10; i<16; i++)  
               p[i] = i;  
          return 0;  
    }  

具体的gflags使用可以参见使用手册,最常用的几个指令如下:

>> gflags.exe /p /enable myapp.exe /full    #对进程myapp.exe完全启用page heap,注意进程名不能带路径

>> gflags.exe /p /disable myapp.exe      #禁止myapp的page heap

>> gflags.exe /p /enable myapp.exe /full /unaligned    #非对齐方式启用page heap

另外值得注意的是:由于gflags会给程序分配大量的保护区间,因此调试的时候会占用大量的内存,一定要保证机器设置了足够的虚拟内存空间,并且在不进行调试的时候及时禁用页堆。



操作步骤如下:

(1).安装好之后,把gflags所在文件夹设置到环境变量的path中,方便命令行使用。(我的电脑-->右键-->属性-->高级-->环境变量-->系统变量-->path)

(2). HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\test.exe写入了PageHeapFlags=0x23

(3). cmd 命令。
            gflags.exe /p /enable myapp.exe /full  
            gflags.exe /p /disable myapp.exe 



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
heap corruption detected: after normal block是一种内存错误,意味着在程序运行时,对于已分配的内存块之后的内存发生了破坏。这个报错通常是由以下几种原因引起的: 1. 内存越界写入:在访问已分配内存块之后的内存时,写入了超出内存边界的数据。这可能导致其他内存块的数据被覆盖或者指向其他非法的内存地址。 2. 释放已释放内存:在释放动态分配的内存块后,继续对该内存进行读写操作。这样做可能导致其他高速缓存区或数据结构出现问题。 3. 重复释放内存:释放一个已被释放的内存块。这种情况可能导致不可预料的结果,例如double free或者对已释放内存的访问。 4. 内存对齐错误:以错误的内存边界或对齐方式分配内存,例如使用不正确的对齐值进行内存分配。这可能会导致内存访问错误。 解决这个问题的方法包括: 1. 检查内存越界问题:检查代码是否存在写入已分配内存块之后内存的错误,并确保所有的内存访问都在边界内。 2. 确保正确的内存释放:在释放内存之后,不再对该内存块进行任何读写操作,并在需要的情况下将指针值设置为null。 3. 防止重复释放:确保每个内存块只被释放一次,并在释放后将指针值设置为null,以防止误用。 4. 确保正确的内存对齐:在分配内存时,使用正确的内存边界和对齐方式,确保内存访问的正确性。 总之,修复heap corruption detected: after normal block错误需要仔细检查代码中的内存操作,并确保操作正确,避免对未分配或已释放的内存进行访问和操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值