2012年10月11日星期四

_CrtSetDbgFlag.Cpp


/*
内存泄露检查
是应用层的,仅限于调试模式(可能也可以用于发行版加_DEBUG)的new,malloc等操作。
对于申请内存的VirtualAlloc和HeapAlloc无效,主要用hook的办法实现。
我从来不用new,delete,malloc,free,所以此办法对我用处不大。
本文参考自:http://msdn.microsoft.com/zh-cn/library/e5ewb1h3(v=vs.90).aspx(启用内存泄漏检测)
*/

//检测内存泄漏的主要工具是调试器和 C 运行时库 (CRT) 调试堆函数。若要启用调试堆函数,请在程序中包括以下语句:

//#include 语句必须采用上文所示顺序。如果更改了顺序,所使用的函数可能无法正确工作。
#define _CRTDBG_MAP_ALLOC //会显示在其中分配泄漏的内存的文件。文件名后括号中的数字是该文件内的行号
#include <stdlib.h>
#include <crtdbg.h>

//通过包括 crtdbg.h,将 malloc 和 free 函数映射到其“Debug”版本 _malloc_dbg 和 _free_dbg,这些函数将跟踪内存分配和释放。
//此映射只在调试版本(在其中定义了 _DEBUG)中发生。发布版本使用普通的 malloc 和 free 函数。

//#define 语句将 CRT 堆函数的基版本映射到对应的“Debug”版本。
//并非绝对需要该语句,但如果没有该语句,内存泄漏转储包含的有用信息将较少。

#include <windows.h>

int main()
{  
    //该语句在程序退出时自动调用 _CrtDumpMemoryLeaks。
    //必须同时设置 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_ALLOC_MEM_DF 两个位域
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

    volatile char * vch = new volatile char[20];
    char * p1 = (char *)malloc( 34 );//这个会显示代码的行号

    LPVOID lpvBase  = VirtualAlloc(NULL, 4096, MEM_RESERVE, PAGE_NOACCESS);
    ULONG_PTR * aPFNs = (ULONG_PTR *) HeapAlloc(GetProcessHeap(), 0, 512);  

    //_CrtDumpMemoryLeaks();//转储内存泄漏信息,加上这一行会重复输出到输出窗口。
    //当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在“输出”窗口中显示内存泄漏信息

    //可以使用以下语句将输出位置设置回“输出”窗口:
    //_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );//加上这一行会重复输出到输出窗口。

    return 0;
}

/*
未定义 _CRTDBG_MAP_ALLOC 时,显示格式的说明:
内存分配编号(在大括号内)。
块类型(普通、客户端或 CRT)。
十六进制形式的内存位置。
以字节为单位的块大小。
前 16 字节的内容(亦为十六进制)。
例如:
Detected memory leaks!
Dumping objects ->
{57} normal block at 0x003D4A30, 20 bytes long.//主要是看这一行。
Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.

转到源文件中分配内存的行的两种办法:注意是:包含文件名和行号的行
1.在“输出”窗口中双击包含文件名和行号的行。
2.在“输出”窗口中选择包含文件名和行号的行,然后按 F4 键。
*/

没有评论:

发表评论