`

[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
分享到:
评论

相关推荐

    [微软标准做法] Visual Studio使用 CRT 库查找C++内存泄漏

    微软提供了一种标准做法,通过Visual Studio集成的C运行时库(CRT)来帮助开发者检测和定位C++程序中的内存泄漏。这篇博文将详细解释如何利用CRT库来查找内存泄漏。 首先,我们需要理解什么是内存泄漏。内存泄漏是...

    网络流媒体Live555源码编译测试工程(Visual Studio 2012 C++实现).rar

    这个"网络流媒体Live555源码编译测试工程(Visual Studio 2012 C++实现)"的压缩包文件提供了在Windows环境下使用Visual Studio 2012编译和测试Live555库的方法。 首先,我们来详细了解Live555的核心功能。Live555...

    iperf 源码和visual studio工程

    源码和Visual Studio工程的提供意味着用户可以在Windows 7环境下使用Microsoft Visual C++(VC)编译器来构建iperf程序,这对于开发者或者网络管理员来说是极其有用的资源。 iperf 的主要功能包括: 1. **TCP和UDP...

    Visual C++开发实例大全(提高卷)光盘源码

    通过《Visual C++开发实例大全(提高卷)》的学习,开发者可以深化对C++语言的理解,提升自己的编程实践能力,同时也能掌握到Visual Studio环境下高效开发的方法。无论是初学者还是经验丰富的开发者,都能从中...

    Visual Studio 2015下编译静态库 jsoncpp-0.5.0(包括release和debug版本的lib)

    在本文中,我们将深入探讨如何在Visual Studio 2015环境下编译jsoncpp-0.5.0这个C++库,以便生成适用于release和debug模式的静态库。jsoncpp是一个开源库,它提供了用于解析、生成JSON(JavaScript Object Notation...

    Debug_C++_

    3. **调试器使用**:GDB(GNU Debugger)是C++开发者常用的命令行调试工具,Visual Studio、Code::Blocks等IDE内置的调试器则提供了图形化界面,便于设置断点、查看变量值、调用堆栈等。 4. **日志记录**:通过在...

    Opencv配置Visual Studio方法

    - **包含目录(Include Directories)**: 在Visual Studio中,打开项目属性,选择“C/C++”-&gt;“常规”-&gt;“附加包含目录”,添加OpenCV的头文件目录,通常是"D:\Program Files\opencv\build\include"。 - **库...

    microsoft visual c++ 库

    在Visual Studio IDE中,开发者可以创建项目,选择不同的配置(如Debug或Release),设定编译器选项,如优化级别、代码生成模式等。IDE还提供了源码编辑、版本控制、调试、测试等多种工具,使得开发流程更为高效。 ...

    TightVnc 2.8.78源码编译,visual studio2017 亲测编译通过,下载即可编译

    1. Visual Studio 2017:这是Microsoft提供的集成开发环境,用于编写、调试和构建各种类型的应用程序,包括C++项目。 2. Microsoft SDKs:这些SDKs包含编译和链接所需的各种工具,例如Windows SDK,确保它与你的...

    C++调用DLL并调试源码

    - 使用Visual Studio或其他IDE,创建一个新的C++项目,选择DLL工程模板。 - 将源码添加到DLL项目中。 - 在调试配置下编译DLL。 2. **附加到进程** - 启动需要调用DLL的宿主程序。 - 在IDE中,选择“调试”&gt; ...

    VC 删除debug文件夹源代码

    在编程领域,特别是使用Microsoft Visual C++(简称VC)进行Windows应用程序开发时,"Debug"文件夹是非常重要的组成部分。这个文件夹包含了调试版本的可执行文件、库、映射文件和其他辅助调试信息。然而,当项目开发...

    Visual Studio 2015下编译静态库 jsoncpp-0.5.0 评.zip

    在本文中,我们将深入探讨如何在Visual Studio 2015环境下编译jsoncpp-0.5.0静态库,以及这个过程中的关键步骤和注意事项。jsoncpp是一个开源的C++库,它允许开发人员处理JSON(JavaScript Object Notation)数据...

    win7Visual Studio2010+CppUnit

    在探讨Visual Studio 2010配合CppUnit进行单元测试的配置和应用时,我们首先需要了解一些基础知识,包括CppUnit单元测试框架的基本概念、Visual Studio 2010的环境配置,以及如何在Windows 7操作系统上将两者结合...

    串口调试助手C++源码(VS 2008)

    【串口调试助手C++源码(VS 2008)】是一个使用Microsoft Visual Studio 2008开发的C++程序,主要用于帮助开发者进行串口通信的调试工作。这个程序提供了用户友好的界面,使得用户能够方便地发送和接收串口数据,...

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

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

    VisualStudio_使用_问题_整理

    《Visual Studio 使用问题整理与解决策略》 Visual Studio作为微软推出的强大的集成开发环境(IDE),在软件开发领域占据着举足轻重的地位。无论是C#、C++、VB.NET还是其他编程语言,开发者都能借助其丰富的功能...

    Qt与visual studio集成:安装与配置.docx

    这里`-debug-and-release`参数意味着编译Qt库的Debug和Release两种模式,`-platform win32-msvc2008`指定了适用于Visual Studio 2008的编译平台,`-opensource`则表示使用Qt的开源版本。 2. **编译Qt源码**: 在...

    球球大作战C++源码

    7. **调试与优化**:项目中的"Debug"目录表明源码可能包含调试信息,可以学习如何使用调试工具(如GDB或Visual Studio的调试器)进行问题定位。同时,源码中也可能涉及到性能优化,例如内存管理、代码优化、多线程...

    Tesseract4.0+VS2015+WIN10 C++ debug和release

    在本文中,我们将深入探讨如何在Windows 10操作系统中,使用Visual Studio 2015(VS2015)编译Tesseract 4.0 OCR引擎的Debug和Release版本。Tesseract是一个开源的OCR(光学字符识别)工具,能够识别图像中的文本并...

    CEF3.2171.1979源码无debug目录

    CEF3.2171.1979源码是中国...开发者需要熟悉C++和CEF的API,以及如何使用Visual Studio来构建和调试项目。同时,由于Flash插件的存在,开发者应该考虑其安全性和兼容性问题,因为Adobe已经停止了对Flash的官方支持。

Global site tag (gtag.js) - Google Analytics