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

关于c++检测内存泄露相关知识(windows程序调试)

1.msdn 在debug模式下的内存结构

(曾今在gaia引擎里看过类似的自己模仿实现的内存管理结构)

typedef struct _CrtMemBlockHeader

{

// Pointer to the block allocated just before this one:

   struct _CrtMemBlockHeader *pBlockHeaderNext;

// Pointer to the block allocated just after this one:

   struct _CrtMemBlockHeader *pBlockHeaderPrev;

   char *szFileName;   // File name

   int nLine;          // Line number

   size_t nDataSize;   // Size of user block

   int nBlockUse;      // Type of block

   long lRequest;      // Allocation number

// Buffer just before (lower than) the user's memory:

   unsigned char gap[nNoMansLandSize]; 

} _CrtMemBlockHeader;

 

/* In an actual memory block in the debug heap,

 * this structure is followed by:

 *    unsigned char data[nDataSize];

 *    unsigned char anotherGap[nNoMansLandSize];//防止内存写越界

 */

 

 

The “NoMansLand” buffers on either side of the user data area of the block are currently 4 bytes in size, and are filled with a known byte value used by the debug heap routines to verify that the limits of the user’s memory block have not been overwritten. The debug heap also fills new memory blocks with a known value. If you elect to keep freed blocks in the heap’s linked list as explained below, these freed blocks are also filled with a known value. Currently, the actual byte values used are as follows:

NoMansLand (0xFD)

The “NoMansLand” buffers on either side of the memory used by an application are currently filled with 0xFD.

Freed blocks (0xDD)

  The freed blocks kept unused in the debug heap’s linked list when the _CRTDBG_DELAY_FREE_MEM_DF flag is set are currently filled with 0xDD.

New objects (0xCD)

New objects are filled with 0xCD when they are allocated.

 


2._CrtDumpMemLeaks()

 

msdn说明

The _CrtDumpMemoryLeaks function determines whether a memory leak has occurred since the start of program execution. When a leak is found, the debug header information for all of the objects in the heap is dumped in a user-readable form. When _DEBUG is not defined, calls to _CrtDumpMemoryLeaks are removed during preprocessing.

_CrtDumpMemoryLeaks is frequently called at the end of program execution to verify that all memory allocated by the application has been freed. The function can be called automatically at program termination by turning on the _CRTDBG_LEAK_CHECK_DF bit field of the _crtDbgFlag flag using the _CrtSetDbgFlag function.

_CrtDumpMemoryLeaks calls _CrtMemCheckpoint to obtain the current state of the heap and then scans the state for blocks that have not been freed. When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all of the objects allocated in the heap from the start of program execution.

By default, internal C run-time blocks (_CRT_BLOCK ) are not included in memory dump operations. The _CrtSetDbgFlag function can be used to turn on the _CRTDBG_CHECK_CRT_DF bit of _crtDbgFlag to include these blocks in the leak detection process.

For more information about heap state functions and the _CrtMemState structure, see the Heap State Reporting Functions . For information about how memory blocks are allocated, initialized, and managed in the debug version of the base heap, see Memory Management and the Debug Heap .

应用:

#include "stdafx.h"
#include <assert.h>
#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 //此部分用于使_CrtDumpMemoryLeaks输出内存泄漏文件名和行号信息默认不会输出相关信息
void Exit
{
    int i = _CrtDumpMemoryLeaks;
    assert( i == 0);
}
int _tmain(int argc, _TCHAR* argv[])
{
    atexit(Exit);
    int* p = new int;
    return 0;
}

不含红色部分输出:

Detected memory leaks!
Dumping objects ->
{112} normal block at 0x003AA770, 4 bytes long.
 Data: <    > 00 00 00 00
Object dump complete.

含红色部分输出:

Detected memory leaks!
Dumping objects ->
d:\code\consoletest\consoletest.cpp(21) : {112} client block at 0x003A38B0, subtype 0, 4 bytes long.
 Data: <    > 00 00 00 00
Object dump complete.

-------------------------------------------------------------------------------------------


1._CrtDumpMemoryLeaks
确定自程序开始执行以来是否发生过内存泄漏,如果发生过,则转储所有已分配对象。如果已使用 _CrtSetDumpClient 安装了挂钩函数,那么,_CrtDumpMemoryLeaks每次转储 _CLIENT_BLOCK 块时,都会调用应用程序所提供的挂钩函数。
 
CrtDumpMemoryLeaks()就是显示当前的内存泄漏。 注意是“当前”,也就是说当它执行时,所有未销毁的对象均会报内存泄漏。因此尽量让这条语句在程序的最后执行。它所反映的是检测到泄漏的地方。
一般用在MFC中比较准确,在InitInstance里面调用_CrtDumpMemoryLeaks

2.信息输出
Detected memory leaks!
Dumping objects ->
{52} normal block at 0x006D2498, 512 bytes long.
?Data: <??????????????? > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{51} normal block at 0x006D2440, 24 bytes long.
?Data: < 4????????????? > 10 34 14 00 FF FF FF FF 00 00 00 00 00 00 00 00
Object dump complete.
3._CrtSetBreakAlloc
知道某个错误分配块的分配请求编号后,可以将该编号传递给 _CrtSetBreakAlloc 以创建一个断点
_CrtSetBreakAlloc(51);这样可以快速在{51}次内存泄漏处设上断点。
 
/*****************************************************************************************************/
最快速度找到内存泄漏
许式伟
2006年11月某日

内存管理是C++程序员的痛。我的《内存管理变革 》系列就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C++程序员的负担。由于工作忙的缘故,这个系列目前未完,暂停。
 
这篇短文我想换个方式,讨论一下如何以最快的速度找到内存泄漏。
 
确认是否存在内存泄漏
我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏。例如:

class  CMyApp :  public  CWinApp
{
public :
   BOOL InitApplication()
   {
        int *  leak  =   new   int [ 10 ];
        return  TRUE;
   }
};
产生的内存泄漏报告大体如下:

Detected memory leaks !
Dumping objects  ->
c:\work\test.cpp( 186 ) : { 52 } normal block at  0x003C4410 ,  40  bytes  long .
 Data:  <                  >  CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
这挺好。问题是,如果我们不喜欢MFC,那么难道就没有办法?或者自己做?

呵呵,这不需要。其实,MFC也没有自己做。内存泄漏检测的工作是VC++的C运行库做的。也就是说,只要你是VC++程序员,都可以很方便地检测内存泄漏。我们还是给个样例:

#include  < crtdbg.h >

inline&n

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