VC++ 内存泄露与检测的一种方法

    本文介绍,当VC++或者MFC程序,出现内存泄露时,如何快速定位的方法,这种方法有一定的局限性,在注意事项中会给出的。

MFC程序

    当MFC程序出现内存泄露时,退出程序时的VS调试输出窗口,一般会有如下显示:

   上面显示了在程序的哪个文件的哪行语句,发生了内存泄露,其中:

   {345}: 表示 内存分配编号

   normal block:表示 内存块类型,有普通块(普通程序分配)、客户端块(分配基于CObject的内存)和CRT块(库函数内部分配)这几种类型

   0x0074A030:以16进制形式输出的内存位置

   40 bytes long: 以字节为单位的内存块大小

   Data<   >CD CD ..:内存块前16个字节的内容,16进制表示。

      定位内存泄露位置,可以双击泄露信息,也可以在输出窗口 按F4键,跳转到 出错行。

 

普通VC++程序

    在普通VC++程序中,要类似MFC中内存检测的效果,需要做如下操作。

    1.  在头文件中,添加  #include <ctrdbg.h>

    2.  在程序入口最开始处,添加 下面两句话即可

        _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );    //设置调试堆函数跟踪分配的方式
        //_CrtSetBreakAlloc();     //这句话,在确实有内存泄露的情况下,给 内存分配编号

    3. 按F5,运行程序,等待程序退出后,在输出窗口可以看到下面的情况:

     

     如图所示,程序有两处内存泄露地方,分配编号为 476 和 475,此时,给_CrtSetBreakAlloc()函数传入476参数,再次运行程序,在退出时,会弹出如下窗口:

    

点击 中断  跳到,_CrtSetBreakAlloc()中断的地方,然后在程序中,通过查看调用堆栈,就可以看到应用程序的哪一次new操作没有执行delete操作。

在中断的同时,也可以从控制台中,看到整个程序析构的顺序,如下图所示:

 

注意事项

1. 当程序确认没有内存泄露时,不可以调用_CrtSetBreakAlloc(475),因为,这样会在指定内存分配次数发生时,强制中断程序。

2. 这种检测内存分配的方式,要求,程序在执行过程中,是可还原的(多次执行过程的内存分配顺序不会发送变化),这个假设,在多数情况下是成立的,不过,在多线程执行的环境下,有时候难以保证。

3. 对于普通C程序,上述检测方法也是成立的,只不过new换成了malloc,delete换成了free

4. 比如 int *p = new int[4]; delete p; 这种方式的泄露,上述方法是检测不出来,此时,需要cppcheck等更有力的工具来检查。

 

参考链接:C++调试堆

时间: 2024-10-14 10:35:54

VC++ 内存泄露与检测的一种方法的相关文章

C++内存泄露和检测

C++中的内存泄露一般指堆中的内存泄露.堆内存是我们手动malloc/realloc/new申请的,程序不会自动回收,需要调用free或delete手动释放,否则就会造成内存泄露.内存泄露其实还应该包括系统资料的泄露,比如socket连接等,使用完后也要释放. 内存泄露的原因: 总结下来,内存泄露大概有一下几个原因: 1.编码错误:malloc.realloc.new申请的内存在堆上,需要手动显示释放,调用free或delete.申请和释放必须成对出现malloc/realloc对应free,n

网络超时检测的三种方法

作者:于老师,华清远见嵌入式学院讲师. 网络通信中,很多操作会使得进程阻塞,这时我们要设定时间,到时间后强制返回,避免进程在没有数据的情况下无限阻塞 这里我们总结一下网络超时检测的三种方法: 通过setsockopt设置套接字属性SO_RCVTIMEO struct timeval t = {5, 0}           if  (setsockopt(listenfd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {             

【代码备忘】VC判断自己窗口的另一种方法

欢迎加入我们的QQ群,无论你是否工作,学生,只要有c / vc / c++ 编程经验,就来吧!158427611 FindWindow就不说了,这说 的是另一种:GetProp 代码也差不多: 查询... HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD); while (::IsWindow(hWndPrevious)) { if (::GetProp(hWndPrevious, _FLAG)) { if (::IsI

[转]浅谈C/C++内存泄露及其检测工具

转自:http://www.cnblogs.com/taoxu0903/archive/2007/10/27/939261.html 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garbage Collection等.Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题:Garbage Collec

内存泄漏及简单检测的一种方法

1.什么是内存泄漏(Memory Leak)? 简单地说就是申请了一块内存空间,使用完毕后没有释放掉.它的一般表现方式是程序运行时间越长,占用内存越多,最终用尽全部内存,整个系统崩溃.由程序申请的一块内存,且没有任何一个指针指向它,那么这块内存就泄露了. 2.内存泄漏的危害性 从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在.真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存.主要有以下几种表现形式: 1)cpu资源耗尽:估计是机器没有反

内存泄露及检测

项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败.内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导致任何问题.实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上.如果程序运行时间足够长,如后台进程运行在服务器上,只要服务器不宕机就一直运行,一个小小的失误也会对程序造成重大的影响,如造成某些关键服务失败. 1.内存泄漏简介 2.Windows平台下的内存泄漏检测

Windows系统中内存泄露与检测工具及方法

1.检测需要使用的工具:windbg工具.检测前,需要先安装windbg工具.安装了该工具后,会在安装目录下有一个umdh工具.假设windbg安装在以下目录下:D:\Program Files\Debugging Tools for Windows (x86) 2.内存泄露检测技巧2.1 运行cmd窗口,将路径设置到安装路径下:2.2 在该cmd窗口中设置环境变量_NT_SYMBOL_PATH:D:\Program Files\Debugging Tools for Windows (x86)

递归很耗内存+多项式求值的两种方法+c语言计时方法

1.用for循环写一个函数,实现从1开始输出到N的正整数. 有两宗实现方法,一种是递归,另一种是非递归 //非递归 void PrintN1(int N){ int i; for(i=1;i<=N;i++){ printf("%d\n",i); } return; } //递归 递归对空间的需求很大,当数字很大的时候,需要很大的内存,当数字是十万的时候递归就崩了 void PrintN2(int N){ if(N){ PrintN2(N-1); printf("%d\n

c/c++内存泄露的检测方法

此文内容摘自 https://zhuanlan.zhihu.com/p/22664202 作为   从零开始的 JSON 库教程(三):解析字符串解答篇  的笔记 1A. Windows 下的内存泄漏检测方法 在 Windows 下,可使用 Visual C++ 的 C Runtime Library(CRT) 检测内存泄漏. 首先,我们在两个 .c 文件首行插入这一段代码: #ifdef _WINDOWS #define _CRTDBG_MAP_ALLOC #include <crtdbg.h