VC++ 堆内存溢出的检测

这篇具有很好参考价值的文章主要介绍了VC++ 堆内存溢出的检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

VC++ 堆内存溢出的检测

关于内存泄漏这样的问题,有些时候在调试程序的过程中可以解决。可是对于堆内存的使用情况,就是供程序员自由分配的内存,是一个

难以快速发现的问题,往往隐藏更深,而且在程序运行过程中表现出来的问题往往是随机的。下面来演示堆内存的情况,如下面所示:

void malloc_test()
{
	test_c* test = new test_c();
	char* test1 = (char*)malloc(100);
	char* test2 = (char*)malloc(6);
	const char* str = "this is a test";
	memcpy(test2, str, strlen(str));
}

在代码中,第 7 行代码将字符串 str 通过内存拷贝的方式复制给 test2。test2 分配了 6 字节,但是复制给它的字符串超过了 6 字节。也就

是说,test2 之外的内存已经被覆盖(超过了 test2 本身的分配空间,已经溢出)。无论这种代码处于编译阶段还是运行阶段,通常情况

下不会有任何提示,运行时也不会有任何问题,所以很难靠肉眼去寻找问题。

调试函数中还有一个函数 _CrtCheckMemory,它会检查在堆栈上分配的每一块内存的完整性。如果分配的内存没有遭到破坏,则返回

true,否则会返回 false,因此我们刚好可以把它用在 ASSERT 宏中。如果 ASSERT 条件为 true,说明我们的代码没有问题;如果为

false,就表示分配的内存出现了问题,会发生中断。我们在 main 函数代码中添加以下命令来提示堆内存是否被破坏:

ASSERT(_CrtCheckMemory());

然后直接按 F5 键启动调试,执行测试程序,弹出了 Debug Assertion Failed!

单击 “重试” 按钮就会定位到调用 _CrtCheckMemory 的位置,表示 _CrtCheckMemory 检查失败,部分内存被破坏。

虽然检查到部分内存已经被破坏,但是程序在退出时才提示信息远远不够,我们无法了解哪些内存被破坏,查找起来并不方便。

_CrtSetDbgFlag 的参数还有一个选项:_CRTDBG_CHECK_ALWAYS_DF,它表示每次分配内存的时候都要检查已经分配的堆内存的完整

性。所以当一块堆内存被破坏时,并不能马上发现问题,而是在下一次分配内存时才会发现已经被破坏的堆内存,从而提示错误信息。所

以,这已经非常接近破坏堆的原始位置。启用 _CRTDBG_CHECK_ALWAYS_DF 选项以后,程序运行的速度会比正常运行速度慢,但是如果

能够即时发现问题,尤其是在开发阶段就能发现问题,这当然是值得的。测试代码如下所示:

void malloc_test()
{
	test_c* test = new test_c();
	char* test1 = (char*)malloc(100);
	char* test2 = (char*)malloc(6);
	const char* str = "this is a test";
	memcpy(test2, str, strlen(str));
	char* test3 = new char[10];
	delete[]test3;
}
int main()
{
	 //启用调试对管理
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
	std::cout << "Memory leak test" << std::endl;
	_CrtSetBreakAlloc(168);
	malloc_test();
	//new_test();
	//_ASSERT(_CrtCheckMemory());
	_CrtDumpMemoryLeaks();	 //显示内存泄漏报告

	return 0;
}

在代码中第 14 行代码调用 _CrtSetDbgFlag 时添加了 _CRTDBG_CHECK_ALWAYS_DF 选项,以便每次分配内存时都检查堆内存的完整

性。在代码的第 33 行,我们对 test2 进行了覆盖操作,然后对 test3 进行内存分配。我们期望程序在分配 test3 时提示错误,并且能够发

生中断。编译程序并按 F5 键启动调试,会弹出错误提示对话框。

此时单击 “重试” 按钮,定位至出错位置。

可以发现,程序是在分配内存时发生中断,说明在这之前破坏了某个堆内存。切换栈帧至分配内存的代码处,即 malloc_test 的 8 行代码

处。

可以发现正在执行分配内存的操作,说明前面的某个操作导致了对某个堆内存的破坏。通过检查代码可以发现,代码的第 7 行处破坏了

test2,从而定位至代码中的堆破坏代码。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器文章来源地址https://www.toymoban.com/news/detail-533852.html

到了这里,关于VC++ 堆内存溢出的检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • C++ Windows进程间共享内存通信

    C++ Windows进程间共享内存通信

    在项目工程中需要64位程序调用32位程序并加以通信。 实现了两个进程间的内存共享。 提示:以下是本篇文章正文内容,下面案例可供参考 1、进程间通信原理: 主要实现: • 系统使用内存映射文件,以便加载和执行. exe和DLL文件。这可以大大节省页文件空间和应用程序启动

    2024年02月03日
    浏览(10)
  • Android之内存泄漏与内存溢出

    Android之内存泄漏与内存溢出

    内存泄漏(memory leak):是指程序在申请内存后,无法释放已申请的内存空间,导致系统无法及时回收内存并且分配给其他进程使用。通常少次数的内存无法及时回收并不会到程序造成什么影响,但是如果在内存本身就比较少获取多次导致内存无法正常回收时,就会导致内存

    2024年02月13日
    浏览(13)
  • 什么是内存溢出?什么是内存泄露?

    什么是内存溢出?什么是内存泄露?

    文章目录 一、什么是内存溢出?  二、什么是内存泄露? 三、如何避免内存溢出和内存泄露? 一、什么是内存溢出?         假设我们JVM中可用的内存空间只有 3M ,但是我们要创建一个 5M 的对象,那么新创建的对象就放不进去了。这个时候,我们就叫做内存溢出。就好

    2024年02月08日
    浏览(12)
  • 什么是内存溢出,什么是内存泄漏?

    什么是内存溢出,什么是内存泄漏?

    提示:以下是本篇文章正文内容,下面案例可供参考 假设我们 JVM 中可用的内存空间只剩下 3M,但是我们要创建一个 5M 的对象,那么,新创建的对象就放不进去了。这个时候,我们就叫做内存溢出。就好比是一个容量只有 300ml 的水杯,我们硬要往里面倒500ml 的水,这时候,

    2024年02月12日
    浏览(12)
  • 内存溢出、内存泄露的概述及常见情形

    内存溢出、内存泄露的概述及常见情形

    java doc 中对 Out Of Memory Error 的解释是,没有空闲内存,并且垃圾收集器也无法提供更多内存。 JVM 提供的内存管理机制和自动垃圾回收极大的解放了用户对于内存的管理,由于 GC(垃圾回收)一直在发展,所有一般情况下,除非应用程序占用的内存增长速度非常快,造成垃圾

    2024年01月21日
    浏览(12)
  • OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法

    OutOfMemoryError内存溢出和StackOverFlowError栈溢出及解决方法

    前一篇: JVM 内存结构 线程的堆栈存储 线程局部原始数据类型、变量、对象的引用、返回值。如果线程堆栈大小超出分配的内存限制,就会出现栈溢出错误。 这里用递归调演示错误 解决方法: 1、修改代码 2、修改栈大小配置 64位电脑默认栈大小为 1024k=1m。可以修改为-Xss2

    2024年02月10日
    浏览(13)
  • Java中的内存溢出与内存泄漏深度解析

    目录 引言 一. 内存溢出(Memory Overflow) 1.1 堆内存溢出 1.2 栈内存溢出 1.3 内存溢出的解决策略 1.3.1 优化对象的创建和销毁 1.3.2 调整堆内存大小 1.3.3  使用内存分析工具 1.3.4 避免创建过大的对象 1.3.5 定期清理不再使用的对象 二、 内存泄漏(Memory Leak) 2.1Java内存泄漏的典

    2024年02月19日
    浏览(14)
  • jvm里的内存溢出

    jvm里的内存溢出

    目录 堆溢出 虚拟机栈和本地方法栈溢出(栈溢出很少出现) 方法区和运行时常量池溢出  本机内存直接溢出(实际中很少出现、了解即可) 堆溢出:最常见的是大list,list里面有很多元 素 堆溢出该怎么解决 :         定位到导致内存溢出的对象         判断是否是

    2024年02月13日
    浏览(14)
  • Step2:Java内存区域与内存溢出异常

    Step2:Java内存区域与内存溢出异常

    对于Java程序员来说,再虚拟机自动内存管理机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,不容易出现内存泄露和内存溢出的问题,看起来由虚拟机管理内存一切都很美好。不过正是因为Java程序员把控制内存的权利交给来Java虚拟机,一旦出现内存泄露方

    2024年02月07日
    浏览(8)
  • Java jvm 内存溢出分析

    Java jvm 内存溢出分析

    我们经常用visualVm监控Jvm的内存,cpu,线程的使用情况,通常可以根据内存不断增长来判断内存是否存在不释放。但是我们不可能时时盯着去看,这里涉及jvm堆内存配置,堆内存参数配置和调优会在其他章节编写。 如果真是内存溢出了,线上出现的我们需要配置JVm内存溢出,

    2024年02月09日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包