当前位置:编程学习 > C/C++ >>

轻轻松松做内存检测

刚接触C++的时候总感觉内存泄露是很可怕的事,觉得手足无措,直到有一天发现心里的巨石居然是那么小的一个case。
方法一:利用CRT调试堆函数
举例说明:
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define  new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif

int main()
{
 char *p = new char[200];
#ifdef _DEBUG
 _CrtDumpMemoryLeaks();
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif

 return 0;
}

输出信息:
Detected memory leaks!
Dumping objects ->
f:\test\highquality\c++primer\main.cpp(10) : {69} normal block at 0x00396990, 200 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

分析:
  {xxx} — 表示程序运行后第xxx次内存分配发生了泄漏,即内存分配编号;
  xxx block — 表示内存块类型,包括三种:普通(normal)、客户端(client)和运行时(CRT);
  at 0x00396990 — 表示发生易做图存地址,用十六进制表示;
  xx bytes long — 表示发生易做图存大小;
  Data:xxx — 表示内存数据信息,一般输出前16字节的内容。

利用_CrtSetBreakAlloc()设置分配指定的内存时,中断,然后查看调用栈。
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define  new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif

int main()
{
 _CrtSetBreakAlloc(69);
 char *p = new char[200];
#ifdef _DEBUG
 _CrtDumpMemoryLeaks();
 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif

 return 0;
}

方法二:使用VLD工具
Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,具有如下特点:  
(1).可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;   
(2).可以得到泄露内存的完整数据;   
(3).可以设置内存泄露报告的级别;   
(4).它是一个已经打包的lib,使用时无须编译它的源代码。而对于使用者自己的代码,也只需要做很小的改动;   
(5).他的源代码使用GNU许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。
1.下载VLD工具 http://www.codeproject.com/tools/visualleakdetector.asp
2.使用 解压之后得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。将.h文件和.lib文件拷贝到你要检测的工程文件所在的目录里(只针对此工程),将dbghelp.dll拷贝到你的程序的运行目录下。
3.用法:在包含入口函数的.cpp文件中加入语句#include "vld.h"即可。
编译正确后,在debug方式下运行:查看VC的输出信息:
有内存泄露显示:"WARNING: Visual Leak Detector detected memory leaks!"
没有内存泄露,此输出的信息为:"No memory leaks detected."
4.举例说明:
#include <iostream>
#include <string>
#include "vld.h"

using namespace std;

int main()
{  
 int *n = new int[10];
 string *s = new string("hello!\n");

 cout << n;
 cout << *s;

 return 0;
}

输出信息中包含以下语句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 84 at 0x003E6CB8: 32 bytes ----------
  Call Stack:
    f:\test\highquality\c++primer\main.cpp (10): main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
    0x7C817077 (File and line number not available): RegisterWaitForInputIdle
  Data:
    00 00 00 00    CD CD CD CD    68 65 6C 6C    6F 21 0A 00     ........ hello!..
    CD CD CD CD    CD CD CD CD    07 00 00 00    0F 00 00 00     ........ ........

---------- Block 83 at 0x003E6C50: 40 bytes ----------
  Call Stack:
    f:\dd\vctools\crt_bld\self_x86\crt\src\newaop.cpp (7): operator new[]
    f:\test\highquality\c++primer\main.cpp (9): main
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
    0x7C817077 (File and line number not available): RegisterWaitForInputIdle
  Data:
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD                                   ........ ........

Visual Leak Detector detected 2 memory leaks.
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[1740] C++primer.exe: 本机”已退出,返回值为 0 (0x0)。

代码改为:
#include <iostream>
#include <string>
#include "vld.h"

using namespace std;

int main()
{  
 int *n = new int[10];
 string *s = new string("hello!\n");

 cout << n;
 cout << *s;

 delete [] n;
 delete s;

 return 0;
}

输出信息中包含以下语句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
No memory leaks detected.
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[4272] C++primer.exe: 本机”已退出,返回值为 0 (0x0)。

 

作者:one_in_one
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,