This may be better directed to Microsoft support, but was wondering if anyone had any ideas as to why this is happening.
I created a simple C++ DLL like the following:
//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(){}
Next, I make a generic MFC SDI (single document interface) application using the default settings in VS 2010. In MainFrm.h I #include "simpledll.h" and create a member variable: simpledll mSimpleDLL;
Here's where it gets interesting. If I compile both the DLL and the MFC application targeting v100 (both using the /MDd switch), simply starting and then closing the application generates a memory leak. If I change the "Use of MFC" setting in the MFC app to use MFC in 开发者_开发问答a static library, the leak goes away. Then, if I recompile the DLL targeting v90 and recompile the MFC app using the DLL version of MFC, no memory leak. Switch the DLL to use v100 and the MFC app to use v90 and no memory leak. In fact, the only combination that seems to generate a memory leak is when both the DLL and the MFC app target v100 and the MFC app is using MFC as a shared DLL. I even tried this with the VS11 developer preview and when targeting v110, everything worked fine.
Has anyone run into this issue? Is it limited just to the SDI MFC app in VS2010? What could be causing these leaks? I'm assuming it has something to do with the DLL being terminated prior to calling the destructor of the SomeString constant, but why would using MFC as a DLL affect that?
I believe it is simply a question of in which order SomeString is initialized versus the call to AfxEnableMemoryTracking() (if I remember correctly). In fact, the memory leak probably happen in the other builds, but SomeString may have been allocated before the memory leak tracking was activated, or it was released before the check happens (unlikely, nothing clear it in the sample).
You can try to make the other build to show the leak by assigning a new value to SomeString, with a longuer string to be sure a new memory allocation is done. Do it from the simpledll's constructor. But first, you have to move the string declaration inside simpledll.cpp file, otherwize you get a new instance into each .cpp that include someHeader.h.
Edit: It is not specific to MFC, that would happens with any DLL, but as MFC automatically enable the memory leak detection, it become more visible in MFC applications.
Two-and-one-half years later ...
I converted a non-trivial standalone application that did not use MFC to a non-MFC DLL that was intended to be loaded by an MFC program. Everything worked, but the VS 2010 debugger reported endless memory leaks.
The clue was that these memory leaks were being reported on exit before the DLL cleanup functions were being called.
There is a detailed discussion with an equally detailed and complex solution here:
http://www.vis-sim.com/3dsceneBB/viewtopic.php?t=1027
that involves specifying MFC library dependencies. There is however a much simpler solution:
- In Property Pages->Linker->Input, add your DLL filename to "Delay Loaded DLLs".
- In the same dialog box tab, add "delayimp.lib" to "Additional Dependencies".
A programmatic alternative (along with a discussion of delay-loaded DLL advantages and disadvantages) can be found here:
http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL
The advantage here is that the delay-loaded DLL is unloaded before the MFC DLL is unloaded, and so MFC no longer reports false memory leaks.
NOTE that this only needs to be done for the DEBUG version your DLL in order to suppress the false memory leak messages. The DLL can still be statically linked in the RELEASE version, thereby avoiding the disadvantages of delay-linked DLLs.
精彩评论