VS2010 报告 DLL 中静态类的错误内存泄漏

2021-12-31 00:00:00 memory-leaks c++ visual-studio-2010

从 Visual Studio DLL 调用 ITK 时内存泄漏的后续问题

我把问题提炼成最简单的例子.

I refined the problem to the simplest example.

struct A
  {
  public:
    A()
      {
      mp_data = new int(0x42);
      }
    ~A()
      {
      delete mp_data;
      }
    int* mp_data;
  };

A a;

在 DLL 中定义这样的全局类时,Visual Studio 调试 CRT 会报告 mp_data 在应用程序关闭时泄漏.除了禁用泄漏报告之外,有人知道解决方法吗?

When such a global class is defined in a DLL, Visual Studio debug CRT reports that mp_data is leaked on application shutdown. Does anybody know a workaround except disabling leak reporting?

推荐答案

如果您在 main 函数的末尾调用 _CrtDumpMemoryLeaks() 行为是预期的,因为 mp_data 将在 _CrtDumpMemoryLeaks() 被调用后被删除.

If you are calling _CrtDumpMemoryLeaks() at the end of the main function the behaviour is expected, since mp_data will be deleted after _CrtDumpMemoryLeaks() was called.

如果您不想调用静态对象的最后一个析构函数(或者更确切地说是在释放内存后的最后一个析构函数中),则需要调用 _CrtDumpMemoryLeaks()看到这些泄漏(相当困难的任务,我不会尝试).

You would need to call _CrtDumpMemoryLeaks() after the last destructor of you static objects has been called (or rather in the last destructor after the memory has been freed) if you don't want to see these leaks (quite a difficult task, I wouldn't try it).

更简洁的方法是在堆上分配所有静态对象(在 main 的开头),并在 main 的末尾取消分配,然后你可以调用 _CrtDumpMemoryLeaks() 并且不会看到任何内存泄漏.

The cleaner approach is to allocate all your static objects on the heap instead (at the beginning of main), and de-allocate them at the end of main, and then you can call _CrtDumpMemoryLeaks() and won't see any memory leaks.

仅供参考,带有构造函数和析构函数的静态对象无论如何都被认为是不好的,因为它们的构造/销毁顺序不是确定性的,并且因为静态对象通常会引入不容易调试的错误.

FYI static objects with constructors and destructors are considered bad anyways, because the order in which they are constructed/destructed is not deterministic, and because of that static objects often introduce bugs which can't be debugged easily.

编辑安德烈的评论:您可以尝试通过调用 _CrtDumpMemoryLeaks 的自动调用.aspx" rel="nofollow noreferrer">_CrtSetDbgFlag 取消设置 _CRTDBG_LEAK_CHECK_DF 标志.如果可行,您可以添加一个静态对象,该对象在其析构函数中调用 _CrtDumpMemoryLeaks().要确保最后销毁此对象,您可以使用 #pragma init_seg(compiler) 指令.

Edit regarding Andrey's comment: You could try to deactivate the automatic call to _CrtDumpMemoryLeaks by calling _CrtSetDbgFlag to unset the _CRTDBG_LEAK_CHECK_DF flag. If that works, you can add a static object which calls _CrtDumpMemoryLeaks() in its destructor. To make sure that this object is destructed last, you can use the #pragma init_seg(compiler) directive.

不知道这是否可行...除此之外,所有其他解决方案很可能需要您修改 ITK 库(这应该是可能的,毕竟它是一个开源库?!).

No clue if this will work... Other than that, all other solutions will most likely require you to modify the ITK library (which should be possible, it's an open source library after all?!).

相关文章