【问题标题】:Detecting memory leaks in MFC application检测 MFC 应用程序中的内存泄漏
【发布时间】:2018-01-17 22:43:43
【问题描述】:

我正在使用 Visual 2017 编写 MFC 应用程序,当应用程序以调试模式退出时,我得到以下信息:

检测到内存泄漏!倾倒对象 -> {74} 普通块 0x00000230E49A7000,16 字节长。数据: 30 00 97 E4 30 02 00 00 00 00 00 00 00 00 00 00 对象转储完成。

所以,为了知道是哪个函数导致了泄漏,我在 stdafx.h 中添加了这些行:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

CWinApp::InitInstance() 中的这些行:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(74);

虽然,它没有工作。我怀疑在我的代码执行之前已经分配了第 74 个内存分配号。我可以重载哪个方法以确保首先被调用?

【问题讨论】:

  • 总是74吗?
  • 是的,它总是 74。我发现内存泄漏发生在我导入项目的非 MFC 代码中。不过,我猜在此代码执行之前不会调用 _CrtSetDbgFlag。
  • 我将这些行放在外部代码主类的构造函数中,当在堆栈上(而不是在堆上)分配 std::vector 时,调试器停止。很奇怪……
  • std::vector 在栈上记住向量可能在栈上,但它是从堆中分配的。
  • 可能泄漏报告是误报。

标签: c++ memory-leaks mfc


【解决方案1】:

进入您的应用程序开始调试(这是一个步骤,而不是运行,因此您将在程序中的任何内容运行之前在调试器中停止),然后将 _crtBreakAlloc 设置为您要停止的分配 (74 )。然后运行,您应该在第 74 次分配时休息一下。 CRT Debug Heap Details 有关于这个变量的信息。

This Microsoft support article 还列出了在调试器中使用_crtBreakAlloc 的说明。

【讨论】:

  • 我这样做了,但调试器在程序结束之前没有中断。但是我想知道一些事情:因为我在 CWinApp::InitInstance() 中调用了 _CrtSetDbgFlag,所以堆插桩激活太晚了,你不觉得吗?
  • @MarkMorrisson 正确。当您调用 _CrtSetBreakAlloc 时,第 74 次分配已经发生,或者您的程序永远不会到达第 74 次分配。
  • 那么,我该怎么办?
  • 请添加调用_CrtSetBreakAlloc(74)的说明;在断点时。我尝试了立即窗口,但它显示identifier "_CrtSetBreakAlloc" is undefined。
  • @ScottHutchinson 您使用_CrtSetBreakAlloc 函数在代码中设置中断计数。在调试器中,设置_crtBreakAlloc 全局变量。
【解决方案2】:

编写这段代码

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

在每个实现 (.CPP) 文件的顶部,可以帮助您检测内存泄漏的来源。 另见:How to detect memory leaks in MFC。

【讨论】:

  • 由于我在我的项目中包含了许多外部文件,因此我在 stdafx.h 的末尾添加了这些行(通常包含在每个源文件中),但效果并不好。
  • 您不能将#define new DEBUG_NEW 添加到stdafx.h 文件的底部。它必须在每个.cpp 文件中。
猜你喜欢
  • 2011-10-09
  • 2020-02-14
  • 2013-04-16
  • 1970-01-01
  • 2012-02-22
  • 2020-09-12
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
相关资源
最近更新 更多