热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

自己动手解决HEAP:FreeHeapblockXXXmodifiedatYYYafteritwasfreed问题

前段时间接手的项目中有出现HEAP:FreeHeapblockXXXmodifiedatYYYafteritwasfreed问题,作为CC++程序员,如果代码写

        前段时间接手的项目中有出现HEAP: Free Heap block XXX modified at YYY after it was freed问题,作为C/C++程序员,如果代码写得不规范,出现这样的问题就不足为奇了。出现这样问题的根本原因就是野指针,即:对已经释放了的内存进行写操作。如:

int* p = new int;
int* pp = p;
delete p;

*pp = 1; //野指针赋值

       在野指针赋值后,如果下次内存分配时,分配到上pp所指地址段,在DEBUG版本调试时,就会在VS的输出窗口出现Free Heap block XXX modified at YYY after it was freed提示。

        出现这样的提示说明代码内存操作有问题,但是不好定位是哪个指针出现了问题。网上很少有真正能解决这样问题的方案,有说使用GFlags,但是它对大项目的支持是相当不足的,因为使用它会额外占用相当多的内存,如果内存不是很宽裕,会导致程序运行非常慢,甚至无法正常工作。btw,我第一次使用它时,由于不熟悉使用方法,直接导致系统所有程序无法开启,系统无响应,无法正常启动系统等等一系列问题,如果不幸你也出现了这样的问题,那请进入安全模式启动系统,使用GFlags把设置改回来即可。

        其实,我们完全可以自己写代码解决这个问题。根据问题,我们知道是因为已经释放了的指针地址(野指针)所在的内容被改变,那么只要我们在释放的内存的时候把地址记录下来,在出现这样问题的时候,从记录中去查找就可以了。

具体步骤如下:

1.重载new操作符,在new操作中记录下内存分配时的相关信息,最重要的是文件名和文件所在行,方便后面出问题时的查找定位。

2.重载delete操作符,在delete操作中记录下已经释放的内存块信息。

3.写一个可以根据地址查找内存块信息的函数。

经过上面的工作,我们就可以在出现问题时直接定位到引起问题的地方了。

实现后,我写了一个简单的测试示例:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int* p = new int;
    int* pp = p;
    delete p;

    *pp = 1;

    p = new int;
    delete p;

    return 0;
}
调试运行时,出现

HEAP[test.exe]: HEAP: Free Heap block 5ed6d8 modified at 5ed71c after it was freed
test.exe 已触发了一个断点

只需要把上面的5ed71c在监视窗口中传入我写的FindBlock函数中就可以看到出现问题所在的文件行了,如下图所示:




推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了一个程序,可以输出1000内能被3整除且个位数为6的所有整数。程序使用了循环和条件判断语句来筛选符合条件的整数,并将其输出。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 如何在跨函数中使用内存?
    本文介绍了在跨函数中使用内存的方法,包括使用指针变量、动态分配内存和静态分配内存的区别。通过示例代码说明了如何正确地在不同函数中使用内存,并提醒程序员在使用动态分配内存时要手动释放内存,以防止内存泄漏。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • Python中程序员的面试题有哪些
    小编给大家分享一下Python中程序员的面试题有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
author-avatar
古镇飞天
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有