C++ 为什么在VisualStudio2010中将MFC用作DLL的MFCSDI程序中使用我的DLL时会泄漏?

C++ 为什么在VisualStudio2010中将MFC用作DLL的MFCSDI程序中使用我的DLL时会泄漏?,c++,visual-studio-2010,dll,memory-leaks,mfc,C++,Visual Studio 2010,Dll,Memory Leaks,Mfc,这可能更好地指向Microsoft支持,但我想知道是否有人知道为什么会发生这种情况 我创建了一个简单的C++ dll,如下所示: //simpledll.h class simpledll { public: __declspec(dllexport) simpledll(); __declspec(dllexport) ~simpledll(); } //someheader.h #include <string> const std::string Some

这可能更好地指向Microsoft支持,但我想知道是否有人知道为什么会发生这种情况

我创建了一个简单的C++ dll,如下所示:

//simpledll.h
class simpledll {
  public:
    __declspec(dllexport) simpledll();
    __declspec(dllexport) ~simpledll();
}

//someheader.h
#include <string>
const std::string SomeString(L"I'm Leaking");

//simpledll.cpp
#include "simpledll.h"
#include "someheader.h"
//some code to generate memory leak debug messages
simpledll::simpledll(){ /*code to register for memory leak debug messages*/}
simpledll::~simpledll(){}
//simpledell.h
类simpledl{
公众:
__declspec(dllexport)simpledl();
__declspec(dllexport)~simpledl();
}
//某物头
#包括
const std::string SomeString(L“我在泄漏”);
//simpledell.cpp
#包括“simpledell.h”
#包括“someheader.h”
//生成内存泄漏调试消息的一些代码
SimpleDell::SimpleDell(){/*用于注册内存泄漏调试消息的代码*/}
SimpleDell::~SimpleDell(){}
接下来,我使用VS2010中的默认设置创建一个通用MFCSDI(单文档接口)应用程序。在MainFrm.h中,我#包括“simpledell.h”并创建一个成员变量:simpledell mSimpleDLL

这就是它变得有趣的地方。如果我编译了针对v100的DLL和MFC应用程序(都使用/MDd开关),只需启动然后关闭应用程序就会产生内存泄漏。如果我更改MFC应用程序中的“使用MFC”设置,以在静态库中使用MFC,泄漏将消失。然后,如果我以v90为目标重新编译DLL,并使用MFC的DLL版本重新编译MFC应用程序,则不会出现内存泄漏。将DLL切换为使用v100,将MFC应用程序切换为使用v90且无内存泄漏。事实上,唯一似乎会产生内存泄漏的组合是当DLL和MFC应用程序都以v100为目标,并且MFC应用程序将MFC用作共享DLL时。我甚至在VS11开发者预览版上尝试过这一点,当我瞄准v110时,一切都很好


有人碰到过这个问题吗?是否仅限于VS2010中的SDI MFC应用程序?是什么导致了这些泄漏?我假设这与调用SomeString常量的析构函数之前终止DLL有关,但为什么将MFC用作DLL会影响这一点?

我认为这只是SomeString的初始化顺序与调用AfxEnableMemoryTracking()的顺序的问题(如果我记得正确的话)。事实上,内存泄漏可能发生在其他构建中,但SomeString可能在内存泄漏跟踪激活之前分配,或者在检查发生之前释放(不太可能,在示例中没有清除它)

您可以尝试让另一个构建显示泄漏,方法是为SomeString指定一个新值,并使用一个longuer字符串来确保完成了新的内存分配。从SimpleDell的构造函数执行此操作。但首先,您必须将字符串声明移动到simpledell.cpp文件中,否则您将在每个包含someHeader.h的.cpp中获得一个新实例


编辑:这并不特定于MFC,任何DLL都会发生这种情况,但随着MFC自动启用内存泄漏检测,它在MFC应用程序中变得更加可见。

两年半后

我将一个不使用MFC的非平凡独立应用程序转换为一个非MFC DLL,该DLL将由MFC程序加载。一切正常,但VS2010调试器报告了无休止的内存泄漏

线索是这些内存泄漏是在调用DLL清理函数之前在退出时报告的

这里有一个同样详细和复杂的解决方案的详细讨论:

这涉及到指定MFC库依赖项。然而,有一个更简单的解决方案:

  • 在属性页->链接器->输入中,将DLL文件名添加到“延迟加载的DLL”
  • 在同一对话框选项卡中,将“delayimp.lib”添加到“其他依赖项”
  • 可在此处找到编程替代方案(以及延迟加载DLL优缺点的讨论):

    这里的优点是在卸载MFC DLL之前卸载延迟加载的DLL,因此MFC不再报告错误的内存泄漏


    请注意,这只需要对DLL的调试版本执行,以抑制错误的内存泄漏消息。在发布版本中,DLL仍然可以静态链接,从而避免延迟链接DLL的缺点。

    Google“静态初始化顺序失败”。谢谢。我确实注意到将所有wstring更改为wchar_t[]解决了这个问题,但不知道为什么。它似乎与MFC static/DLL绑定的事实仍然让我感到奇怪。