【问题标题】:Detected memory leaks检测到内存泄漏
【发布时间】:2012-01-22 13:34:27
【问题描述】:

在我的 wxWidgets 应用程序中,在调试模式下运行时,我在 Visual Studio 2010 的输出中收到此消息。该应用程序运行良好,我只是在关闭它后才看到。

检测到内存泄漏!

转储对象 ->

{9554} 0x003CDCC0 处的普通块,44 字节长。
数据: 20 C1 65 01 01 00 00 00 6E 00 00 00 9C CE 64 01

{9553} 0x003CDB58 处的普通块,8 字节长。

数据: 44 BD 65 01 C0 DC 3C 00
{9552} 0x003CDC50 处的普通块,48 字节长。

数据:A0 95 65 01 01 00 00 00 19 00 00 00 19 00 00 00

对象转储完成。

在我的程序中,我没有明确分配内存,但是 wxWidgets 框架是。第一次收到这样的消息,不知道具体原因。

我怎样才能摆脱这种内存泄漏?

【问题讨论】:

  • 发布您的代码,最好是重现问题的最小程序。
  • 不幸的是我不能发布一个最小的程序。因为,它是一个包含多个文件的 GUI 程序,以及一个 GUI 框架。我不知道是什么原因造成的。因为我没用过newmalloc
  • 我只是担心你会得到比答案更多的猜测:)

标签: c++ visual-studio-2010 memory-leaks wxwidgets


【解决方案1】:

您只需在 main 函数的开头添加以下行。添加此标志后,Visual Studio 将在造成内存泄漏的行中断。

    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _CrtSetBreakAlloc(9554);
    _CrtSetBreakAlloc(9553);
    _CrtSetBreakAlloc(9552);

确保您拥有正确的对象普通块地址,因为它们可能会更改并确保您在 _DEBUG 上进行编译。

另请参阅:_CrtSetDbgFlag_CrtSetBreakAlloc

【讨论】:

  • 谢谢,真正对我有用的是添加_crtBreakAlloc = 9609; 作为第一个声明。对于 wxWidgets,我必须将其添加到主应用程序的 OnInit() 函数中。
  • 嗨,你是怎么想到 9609 的?
  • @bluepiranha 指的是括号中开头的数字。因此,在他的情况下,他在 {9609} 报告了一个。 (我知道这是一条旧评论;这也是为像我这样寻找此信息的人准备的)。
  • 可能还值得注意的是,如果您手动调用_CrtCheckMemory(),而不是使用调试标志在程序退出时运行它,使用堆的静态变量将显示为泄漏 - 而_CrtSetBreakAlloc() 不会为它们触发,因为它们在 main() 运行之前被初始化。
【解决方案2】:
  1. 永远不要只是“假设”您的代码是内存泄漏证明的。除非你是编程半神之一,否则没有人能免于写内存泄漏。

  2. 您可以使用边界检查器(来自 Microfocus)之类的工具来帮助识别内存泄漏,因为它会给您一个调用堆栈。您从调试 CRT 获得的内存泄漏报告只是告诉您内存在特定地址泄漏。诸如边界检查器之类的产品将为您提供该内存泄漏的调用堆栈,以及许多其他好东西。市场上还有其他内存泄漏工具,但我不会在此列出。

  3. 如果您确定内存泄漏是由“wxWidgets”引起的,那么也许您应该通知该库的编写者,也许他们会修复它(使用适当的重现步骤)。

【讨论】:

  • 我从来没有说过我的代码是内存泄漏证明,只是我没有在我的代码中使用 new 或 malloc。是的,也许我应该尝试在 wxWidgets 网站上询问它。
【解决方案3】:

也许某些类型的静态实例仍然由框架分配。尝试使用像“devpartner”这样的分析器来解决它。

【讨论】:

  • Visual Studio 发来的消息可以用来获取帮助吗?
  • @VinayakGarg 可以提供帮助,但用途非常有限。列出的Data其实就是内存地址的内容,通过它你可以猜出这块内存是用来做什么的,猜猜它分配在哪里。
  • @CJohnson 你说得对,他需要其他分析器我会改变它:) 谢谢。
【解决方案4】:

This wiki 建议将以下内容添加到您拥有的每个源文件中,在所有其他标头包含之后:

#ifdef __WXMSW__
    #include <wx/msw/msvcrt.h>      // redefines the new() operator 
#endif

这将导致程序结束时报告泄漏。

更具体地说,请确保对使用 new 创建的所有对象调用 -&gt;Destroy()(可能除了您的顶部窗口)。

【讨论】:

    【解决方案5】:

    如果每次 vs 报告的泄漏位置都相同,您可以设置一个数据断点以查看此内存何时被更改,并希望找出谁在分配此内存

    【讨论】:

      猜你喜欢
      • 2012-07-16
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      相关资源
      最近更新 更多