为什么在DLL中使用MFC作为Visual Studio 2010中的DLL在MFC SDI程序中使用我的DLL时会泄漏?

问题描述 投票:4回答:3

这可能更适合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(){}

接下来,我使用VS 2010中的默认设置制作一个通用的MFC SDI(单文档界面)应用程序。在MainFrm.h中,我#include“ simpledll.h”并创建一个成员变量:simpledll mSimpleDLL;

在这里变得很有趣。如果我同时编译DLL和针对v100的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应用程序吗?是什么导致这些泄漏?我假设它与DLL在调用SomeString常量的析构函数之前被终止有关,但是为什么将MFC作为DLL会影响它呢?

c++ visual-studio-2010 dll memory-leaks mfc
3个回答
0
投票

我相信这只是一个简单的问题,即初始化SomeString的顺序与对AfxEnableMemoryTracking()的调用(如果我没记错的话)。实际上,内存泄漏可能在其他版本中发生,但是SomeString可能是在内存泄漏跟踪被激活之前分配的,或者在检查发生之前被释放的(可能没有清除示例中的内容)。

您可以通过为SomeString分配一个新的值,并使用一个较长的字符串,以确保完成了新的内存分配,尝试制作另一个版本来显示泄漏。从simpledll的构造函数执行此操作。但是首先,您必须将字符串声明移至simpledll.cpp文件中,否则您将在包含someHeader.h的每个.cpp中获得一个新实例。

编辑:它并非特定于MFC,任何DLL都会发生,但由于MFC自动启用内存泄漏检测,因此在MFC应用程序中变得更加明显。


0
投票

两年半后...

我将不使用MFC的非平凡的独立应用程序转换为旨在由MFC程序加载的非MFC DLL。一切正常,但是VS 2010调试器报告了无尽的内存泄漏。

线索是这些内存泄漏是在出口之前]报告的,正在调用DLL清理功能。

这里进行了详细的讨论,并提供了同样详细和复杂的解决方案:

http://www.vis-sim.com/3dsceneBB/viewtopic.php?t=1027

涉及指定MFC库依赖关系。但是,有一个更简单的解决方案:

  1. 在属性页->链接器->输入中,将您的DLL文件名添加到“延迟加载的DLL”。
  2. 在同一对话框选项卡中,将“ delayimp.lib”添加到“其他依赖项”。
  3. 可以在这里找到一种编程替代方法(以及有关延迟加载的DLL的优缺点的讨论:

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

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

注意,仅对于DLL的DEBUG版本,才需要这样做,以便抑制错误的内存泄漏消息。 DLL仍可以在RELEASE版本中静态链接,从而避免了延迟链接的DLL的缺点。


0
投票

问题在v141(vs2017)中仍然存在。

© www.soinside.com 2019 - 2024. All rights reserved.