`

[DEBUG阶段][源码] Visual Studio 下C++内存泄露检测

 
阅读更多
转自
http://www.cnblogs.com/zouzf/p/4152279.html

相关文章
http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html
http://blog.csdn.net/KangRoger/article/details/39317503

参考文章:
http://msdn.microsoft.com/zh-cn/library/x98tx3cf.aspx
http://www.cnblogs.com/jianqiang2010/archive/2010/12/02/1894327.html
http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html


1、在main方法所在的文件里加上如下代码:
//可以定位到发生内存泄露 所在的文件和具体那一行,用于检测 malloc 分配的内存
#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h>
#include <crtdbg.h>

//把分配内存的信息保存下来,可以定位到那一行发生了内存泄露。用于检测 new 分配的内存
#ifdef _DEBUG
#define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

//有用
inline void EnableMemLeakCheck()
{
    //该语句在程序退出时自动调用 _CrtDumpMemoryLeaks(),用于多个退出出口的情况.
    //如果只有一个退出位置,可以在程序退出之前调用 _CrtDumpMemoryLeaks()
   _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}



2、在main方法里开始的地方调用 EnableMemLeakCheck() 方法。到此为止,可以检测的内存泄露的信息里,有一部分是可以定位到具体的文件以及所在的行的,但还是有一些其他工程或者其他文件里如果发生内存泄露还是没有定位到具体的文件和行,这些信息会在vs的输出窗口里看到。如下面的输出,第一处泄露有很具体的定位信息,第二处的泄露却没有。

引用

q:\project_wydxml\wydxmlcreator\project_win32\wydxmlcreator.cpp(52) : {256} normal block at 0x00ABBC40, 200 bytes long.
Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
{254} normal block at 0x00ABF6F8, 10 bytes long.
Data: <          > CD CD CD CD CD CD CD CD CD CD



3、对于那些没有定位出具体位置的内存泄露处理如下:记录下该处内存是第几次分配的,比如上面的第三行和第四行表示第二处内存泄露,第三行里 {}里的254表示该处泄露的内存是第 254 次分配的。结束运行,在 EnableMemLeakCheck() 方法 后加上一句代码: _CrtSetBreakAlloc(254); 括号里的参数就是没有得到准确定位的泄露内存的被分配的序数,其他的就别改了,再次运行,程序就会在 分配 第 254 块 内存时进入断点,通过断点堆栈就可以比较方便的知道哪些泄露了。

4、注意事项:对于 new 出来的一些自定义类的对象,直接调用其析构方法时,EnableMemLeakCheck 还是会将其视作没有释放内存的,要直接调用 delete xxx 才行。。。如: A *a = new A();  a->~A(); 会被判做有问题的, delete a 才视作没问题。。。。

5、令外,还有个监控某片代码段是否有内存泄露的,如下。如果有这段代码有泄露,_CrtMemDifference就会比较出来,然后 _CrtMemDumpStatistics输出相关信息。输出的信息没有具体的定位到具体文件具体哪一行,但有时还是有些辅助作用的吧
_CrtMemState s1, s2, s3;
_CrtMemCheckpoint( &s1 );

//your code

CrtMemCheckpoint( &s2 );
if ( _CrtMemDifference( &s3, &s1, &s2) )
     _CrtMemDumpStatistics( &s3 );


全部代码如下:
#include "stdafx.h"
#include <iostream>
#include "wydxml.h"

//可以定位到发生内存泄露 所在的文件和具体那一行,用于检测 malloc 分配的内存
#define _CRTDBG_MAP_ALLOC 
#include <stdlib.h>
#include <crtdbg.h>

//把分配内存的信息保存下来,可以定位到那一行发生了内存泄露。用于检测 new 分配的内存
#ifdef _DEBUG
#define new   new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

//有用
inline void EnableMemLeakCheck()
{
    //该语句在程序退出时自动调用 _CrtDumpMemoryLeaks(),用于多个退出出口的情况.
    //如果只有一个退出位置,可以在程序退出之前调用 _CrtDumpMemoryLeaks()
   _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
}


int _tmain(int argc, _TCHAR* argv[])
{
    
    EnableMemLeakCheck();

    //运行到 第 191 次 内存分配的时候停下来
    //_CrtSetBreakAlloc(191);

    char* p = new char[100];
    char* p1 = new char[200];
    char* p2 = (char*)malloc(600);
    delete p;

    getchar();

    //_CrtDumpMemoryLeaks();//这个代码好像会输出额外多余的内存分配信息
    return 0;
}



以下转自
http://www.cnblogs.com/huhuuu/p/3576710.html

C++没有java的内存垃圾回收机制,在程序短的时候可能比较容易发现问题,在程序长的时候是否有什么检测的方法呢?

  假设有一个函数可以某点检测程序的内存使用情况,那是否可以在程序开始的时候设置一个点,在程序结束的时候再设置一个点,比较这两个值是否一样就可以知道内存泄露的情况了。

  windows下的内存检测方法:
#define _CRTDBG_MAP_ALLOC //一定要加上这一句
#include <stdlib.h>
#include <crtdbg.h>

#include <iostream>
using namespace std;

_CrtMemState s1, s2, s3;

void GetMemory(char *p, int num)
{
    p = (char*)malloc(sizeof(char) * num);
}

int main(int argc,char** argv)
{
    _CrtMemCheckpoint( &s1 ); //检测当前内存的使用情况
    char *str = NULL;
    int n=1000;
    GetMemory(str, 100);//这里申请后没有释放内存,内存泄露了

    _CrtMemCheckpoint( &s2 ); 

    _CrtMemDifference( &s3, &s1, &s2); //比较s1,s2的内存差异,结果放s3
    printf("%ud",s3.lTotalCount);

    return 0;
}


    之前一直没有搞清楚_CrtDumpMemoryLeaks();的调用方法,因为之前执行程序都是ctrl + F5的,原来发现这个函数是在F5的时候生效

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK  new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

int main()
{
    
    int* p = new int(); 
    int n=5;
    while(n--){
        new int;
    }
    _CrtDumpMemoryLeaks();

    return 0;
}




嗯,编译器提示有6个内存块内存泄露了。

同时,注意其中也显示了内存泄露的行号,利于调试。



在linux下也有类似的方法

参考:http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html
分享到:
评论

相关推荐

    基于C++OpenCV实现的直线检测、圆检测.zip

    资源包含文件:设计报告word+源码及可执行exe文件 ...开发平台:Visual Studio 2019 Debug x64 详细介绍参考:https://biyezuopin.blog.csdn.net/article/details/125257468?spm=1001.2014.3001.5502

    基于C++OpenCV实现的Harris角点特征检测.zip

    资源包含文件:设计报告word+项目源码及可执行EXE文件 读入摄像头,可以实时回放视频。键盘交互,空格键暂停,并对当前帧图像做一次 Harris Corner 检测,并...开发平台:Visual Studio 2019 Debug x64 详细介绍参考:

    Visual C++ 编程资源大全(英文源码 其它)

    05.zip Finding memory leaks 发现内存的泄漏(6KB)&lt;END&gt;&lt;br&gt;6,06.zip Convert message ID to a string 将消息标志符转换成字符串(4KB)&lt;END&gt;&lt;br&gt;7,07.zip Message Tracer 消息跟踪(5KB)&lt;END&gt;&lt;br&gt;8,...

    基于C++ 和OpenGL的太阳系(太阳、地球、月球)系统运动图绘制源码+使用说明+exe.zip

    基于C++ 和OpenGL的太阳系(太阳、地球、月球)系统运动图绘制源码+使用说明+exe.zip 运行环境 - `windows 11` - `Visual Studio 2022` - `OpenGL` * `glfw-3.3.8.bin.WIN64` * `glutdlls37beta` # 不配置环境 ...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

    《visual c++ 2010入门经典(第5版)》针对visual c++ 2010版本进行了全面更新,介绍了最新的开发环境和如何使用visual c++构建现实世界中的应用程序。拥有本书,您就迈向了通往使用两种c++版本编写应用程序的成功之路...

    eclipse 开发c/c++

    代码辅助:这个代码完成功能类似于可在 Borland C++ Builder 或 MS Visual Studio 中找到的功能。 它使用了 代码模板,并且只有助于避免愚蠢的语法错误: 图 4. 有助于使用正确的语言语法的代码辅助功能 代码模板...

    实用与学习软件系列(7) JavaEditor Java集成开发环境(含源码)

    以Eclipse,Visual Studio.Net开发环境为参照,提供了除debug,UI设计器外的很多主要功能,包括基于语法和最近使用原则的拼写和鼠标逗留智能提示,错误自动定位及鼠标提示,自动编译,集成的命令行控制台,工程式的...

    boost_1_58_0--vs2015--x64--debug.rar

    rocketMQ 官方提供的C++ sdk工程源码质量不高,编译过程中会有许多报错,包含工程文件环境设置遗漏、源码bug更新不及时等问题,给使用者带来不便。似乎官方对C++sdk不太重视,可能和rocketMQ 的关注度低有关。在这里...

    dlib_19.15编译完的版本(包含源码)

    dlib19.15采用cmake和visual studio 2017编译后得到dlib.lib的debug和release两个版本,可用于C++版本的face detection。 (注意本人是win7 64位系统,32位系统千万不要下载!!!)

    rocketmq-client-cpp.lib

    rocketMQ 官方提供的C++ sdk工程源码质量不高,编译过程中会有许多报错,包含工程文件环境设置遗漏、源码bug更新不及时等问题,给使用者带来不便。似乎官方对C++sdk不太重视,可能和rocketMQ 的关注度低有关。在这里...

    H1Z1-Tool:开源H1Z1地图&工具修改

    (如果您尝试在调试/发布模式下使用 Visual Studio 运行它,请确保将数据文件夹 (dist/data) 复制到 (build/DEBUG , build/RELEASE)) H1Z1Tool包括以下功能 - General DirectX9 external overlay - World ...

    rocketmq-client-cpp vs2015 x64 Debug.rar

    rocketMQ 官方提供的C++ sdk工程源码质量不高,编译过程中会有许多报错,包含工程文件环境设置遗漏、源码bug更新不及时等问题,给使用者带来不便。似乎官方对C++sdk不太重视,可能和rocketMQ 的关注度低有关。在这里...

    修正的win32平台的opencv3.2.0

    之前传的"win32平台的...在VS2010上也可以使用release版本(opencv_world320.lib,opencv_world320.dll),就是需要安装"Visual C++ Redistributable for Visual Studio 2015",这个方法也测试通过了。欢迎大家交流学习。

    seti_fpga:SETI @ Home到FPGA平台的端口

    使用Visual Studio 2005打开和构建以下两个解决方案: boinc-old / win_build / boinc.sln seti_boinc / client / win_build / seti_boinc.sln 要做的事情: [1]将所有与seti_boinc.sln相关项目的引用从boinc更改...

    rocketmq-client-cpp.dll

    rocketMQ 官方提供的C++ sdk工程源码质量不高,编译过程中会有许多报错,包含工程文件环境设置遗漏、源码bug更新不及时等问题,给使用者带来不便。似乎官方对C++sdk不太重视,可能和rocketMQ 的关注度低有关。在这里...

    Opencv 411完整编译(内含Opencv411-contrib拓展模块),已经通过Cmake和VS2019编译通过直接使用

    但编译过程真的一言难尽,对于不熟悉cmake编译环境,或者visual studio的小伙伴们往往BUG频出。为了能解决大家在编译上的问题,减少不必要的时间浪费,这里博主为大家提供已经编译好的Opencv+contirb(411)的安装包...

    ICS delphixe10源码版

    ICS - Internet Component Suite - V8 - Delphi 7 to RAD Studio 10 Seattle ======================================================================= (Aka FPIETTE's Components) Revised: March 3, 2016 ...

    用 vs2017 写支持库-易语言

    —— 工程源码、库、头文件等; JBzlib.sln  —— 解决方案,安装好 vs2017 双击运行直接可以编译。 先不急着打开解决方案,先打开 JBzlib 文件夹: elib —— 实际上就是易的安装目录下的 sdk 文件夹中的 elib,也...

    VS2010 + OpenCV2.4.3 + Windows Form Application

    Configure: 选择 Visual Studio 10/? Generate: 生成目标 3.打开D:/OpenCV/Resources/OpenCV-2.4.3/opencv/vs2010,用对应版本的VS打开OpenCV.sln... A.编译OpenCV方案Debug版本: 1,编译OpenCV方案(Debug): 在VS工作...

    MATLAB生成cuda代码使用-registration_CUDA:本项目基于matlab的dftregistration函数。主要用于解决

    不带GPU后缀的文件夹为C++源码。 Test项目为测试DLL是否生成成功,且可用。 使用方法: 将test*.cpp文件里的图像大小和张数以及路径修改为适用于自己的。 GPU版本的函数最后输入的一个参数是同时并行处理的图像张数...

Global site tag (gtag.js) - Google Analytics