定位内存泄漏

Locating Memory Leaks

本文关键字:泄漏 内存 定位      更新时间:2023-10-16

我目前正在调试一些代码,使用Visual Studio 2012和CrtDbg删除或至少定位内存泄漏。

问题是,只要分配号不改变,跟踪分配是相当容易的。当分配数变化很大(或者不确定)时,如何定位泄漏的分配点?我至少可以说一下,是哪个模块分配了内存?

我有以下几行关闭应用程序:

Detected memory leaks!
Dumping objects ->
{2789444} normal block at 0x0000000006103CB0, 32 bytes long.
 Data: < q f            > B8 71 E4 66 00 00 00 00 00 00 00 00 00 00 00 00 
{1269709} normal block at 0x000000000A50C6A0, 1008 bytes long.
 Data: <        )       > 01 00 00 00 0B 00 00 00 29 00 00 00 CD CD CD CD 
...
{2194} normal block at 0x0000000000278060, 16 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
Object dump complete.

最后一个分配号2194是可重复的,并且与静态初始化式有关。但其他数字正在变化。

我不能用地址找到它吗?或者有更简单的解决方案吗?

如果能帮忙就好了

我建议您使用视觉泄漏检测器。我应该给你所有你需要的细节,这样你就可以追踪泄漏,而且很容易安装。看到

尝试调试诊断工具v2.0,这是一个非常好的内存检测器工具在Windows上,它是来自微软,它是免费的。

如果第三方库泄漏内存,该工具可以定位该库,而不需要调用堆栈信息。

要通过此调试器启动exe,请转到菜单"工具"->"预附加配置",为exe启用预附加调试器。

您可以使用这些技巧:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
class MemChecker 
{
   friend class foo;
   struct foo 
   {
      HANDLE hLogFile;
      _CrtMemState _ms; 
      foo() 
      {
         hLogFile = CreateFile(TEXT("memory_leaks.txt"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
         _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); // enable file output
         _CrtSetReportFile( _CRT_WARN, hLogFile ); // set file to stdout
         _CrtMemCheckpoint(&_ms); // now forget about objects created before
         // breaks on N-th memory allocation
         // look for this number in report file (in curved brackets)
         //_CrtSetBreakAlloc(1518);
      }
      ~foo() 
      { 
         _CrtMemDumpAllObjectsSince(&_ms); // dump leaks
         CloseHandle(hLogFile);
      }
   };
   static foo obj;
};
MemChecker::foo MemChecker::obj;

使用此声明,每次运行程序时都会以适当的方式检测和报告内存泄漏。

同样,您可以将断点设置为特定的内存泄漏(请阅读代码中的注释)。如何做到这一点:你运行应用程序,看看,内存泄漏的数量,然后你设置_CrtSetBreakAlloc(2789444*),所以下次你运行应用程序-它打破的地方,内存(泄漏)被分配。

您可以更仔细地阅读标志_CRTDBG_MODE_FILE, _CRTDBG_MODE_DEBUG,以指定调试消息将输出的位置。

*从你的例子,{2789444}正常块在0x0000000006103CB0, 32字节长。

下载视觉泄漏检测器并开始以下操作:

创建如下目录结构:

Visual Leak Detector
    include
        vld.h
        vld_def.h
    lib
        Win32
            vld.lib
        Win64
            vld.lib
    bin
        Win32
            vld_x86.dll
        Win64
            vld_x64.dll

在主函数上面添加以下代码:

#ifdef _DEBUG_MEM
#include <vld.h>
#endif

在项目设置中添加以下内容:

_DEBUG_MEM in the preprocessor-definitions
Visual Leak Detectorinclude in the include-path
Visual Leak DetectorlibWin<xx> in the library-path
Visual Leak DetectorbinWin<xx> in the executable-path