Its a good practise if we don't depend on IDE/third-party tools/software to detect memory leaks in our code. Its better if we can predict before hand the consequences of writing each line of code.
But there may be situations where we need to work on projects written by someone else. In such cases these third-party tools may help us in finding a QUICK solution.
The visual studio debugger along with C run-time (CRT) libraries provides us means for detecting memory leaks.But its capabilities are minimal.
Enabling memory leak detection in visual studio:
1. If our program can exit from multiple locations, instead of putting a call to _CrtDumpMemoryLeaks at each possible exit,include the following call at the beginning of program:
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
This statement automatically calls _CrtDumpMemoryLeaks when program exits.
2 . The macro _CRTDBG_MAP_ALLOC applies to c library functions malloc, realloc.With a little bit of extra code, we can get it to work with new/delete:
#define _CRTDBG_MAP_ALLOC
#include <iostream>
#include <crtdbg.h>
#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
These macros should be added after including all other header files.
3. By default, _CrtDumpMemoryLeaks dumps memory leak information to the Output window,we can reset this to a file using _CrtSetReportMode. For doing this add the following lines of code at the starting of your program.
HANDLE hLogFile;
hLogFile = CreateFileA("c:\\memoryLeaksDump.rtf", GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, hLogFile);
_CrtSetReportFile(_CRT_ERROR, hLogFile);
_CrtSetReportFile(_CRT_ASSERT, hLogFile);
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
Martin T. wrote:
Why does MFC call _CrtDumpMemoryLeaks ?!?
11-Jul-08
(I think this applies to mfc & C++ & debugging, hence the 3 NG)
OK, maybe this'll be some kind of rant, but I really don't get it and it
would really be nice to know what the rationale behind the "built-in"
memory leak detection of MFC is, when any user could provide it on his
own without false memory leaks ...
Explanation:
The Run-Time Library provides for Debug Routines that (among other
things) allow reporting of memory-leaks.
It is possible to enable *automatic* reporting for the CRT by calling
the function _CrtSetDbgFlag(...) with the _CRTDBG_LEAK_CHECK_DF flag.
If you choose to enable this *automatic* check in your C++ program, the
CRT will happily (and most correctly) report all left-over memory via
_CrtDumpMemoryLeaks *after* basically all non-system DLLs have been
unloaded.
Enter MFC:
For reasons unknown to me (but probably historical or some such $%&$)
/if/ your Application links against the MFC DLL /then/ within the d'tor
of a class called _AFX_DEBUG_STATE (atlmfc/src/mfc/dumpinit.cpp, ln 123)
MFC will call _CrtDumpMemoryLeaks and afterwards disable the reporting
on process-end:
_AFX_DEBUG_STATE::~_AFX_DEBUG_STATE()
{
_CrtDumpMemoryLeaks();
int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag(nOldState & ~_CRTDBG_LEAK_CHECK_DF);
ASSERT(_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE,_AfxCrtReportHook) != -1);
_CrtSetDumpClient(pfnOldCrtDumpClient);
}
Not only is this completely unnecessary, as you could (if you so wished)
tell the CRT to dump it on process end - oh no! It is quite horrible if
you use a 3rd party C++ DLL that happens to hold memory in global static
objects that will only be destroyed when this DLL is unloaded and does
*not* link against MFC.
That is because in all my test cases any user-supplied DLL (project
dependency, via Linker-Input:lib) is always unloaded *after* the MFC-DLL
(mfc80ud.dll in my case).
In this scenario the stupid call of _CrtDumpMemoryLeaks from the MFC
cleanup code will report all this memory as leaks, even though it *will*
be cleaned up --- it just happens that the code had the cheek to not use
MFC.
* You can't work around it, as you cannot change DLL (static)
load/unload order.
* You can't work around it, as you cannot use a C++ DLL with
LoadLibrary/FreeLibrary.
* You can't work around it, as you cannot tell MFC not to report this
false memleaks and use the CRT mechanism instead.
* You can't work around it, as your main application needs to use MFC.
* You can't work around it, as the 3rd party DLL cannot, in general, be
made to link against MFC (thereby forcing a later unload of mfc80ud.dll)
* You can't even ignore the MFC dump and additionally use the CRT dump
as MFC will switch it off after it dumped!
Bah!
So ... I'm stuck with a program that dumps 2000 memory leaks at
MFC-cleanup that are false and will obscure any real (and possibly
problematic) memleaks I would like to find ...
It would be interesting to hear from someone who knows a rational behind
the MFC code or has some general thoughts how to get around it or to
hear why I'm completely mistaken :)
cheers,
Martin
Previous Posts In This Thread:
On Friday, July 11, 2008 9:28 AM
Martin T. wrote:
Why does MFC call _CrtDumpMemoryLeaks ?!?
(I think this applies to mfc & C++ & debugging, hence the 3 NG)
OK, maybe this'll be some kind of rant, but I really don't get it and it
would really be nice to know what the rationale behind the "built-in"
memory leak detection of MFC is, when any user could provide it on his
own without false memory leaks ...
Explanation:
The Run-Time Library provides for Debug Routines that (among other
things) allow reporting of memory-leaks.
It is possible to enable *automatic* reporting for the CRT by calling
the function _CrtSetDbgFlag(...) with the _CRTDBG_LEAK_CHECK_DF flag.
If you choose to enable this *automatic* check in your C++ program, the
CRT will happily (and most correctly) report all left-over memory via
_CrtDumpMemoryLeaks *after* basically all non-system DLLs have been
unloaded.
Enter MFC:
For reasons unknown to me (but probably historical or some such $%&$)
/if/ your Application links against the MFC DLL /then/ within the d'tor
of a class called _AFX_DEBUG_STATE (atlmfc/src/mfc/dumpinit.cpp, ln 123)
MFC will call _CrtDumpMemoryLeaks and afterwards disable the reporting
on process-end:
_AFX_DEBUG_STATE::~_AFX_DEBUG_STATE()
{
_CrtDumpMemoryLeaks();
int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag(nOldState & ~_CRTDBG_LEAK_CHECK_DF);
ASSERT(_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE,_AfxCrtReportHook) != -1);
_CrtSetDumpClient(pfnOldCrtDumpClient);
}
Not only is this completely unnecessary, as you could (if you so wished)
tell the CRT to dump it on process end - oh no! It is quite horrible if
you use a 3rd party C++ DLL that happens to hold memory in global static
objects that will only be destroyed when this DLL is unloaded and does
*not* link against MFC.
That is because in all my test cases any user-supplied DLL (project
dependency, via Linker-Input:lib) is always unloaded *after* the MFC-DLL
(mfc80ud.dll in my case).
In this scenario the stupid call of _CrtDumpMemoryLeaks from the MFC
cleanup code will report all this memory as leaks, even though it *will*
be cleaned up --- it just happens that the code had the cheek to not use
MFC.
* You can't work around it, as you cannot change DLL (static)
load/unload order.
* You can't work around it, as you cannot use a C++ DLL with
LoadLibrary/FreeLibrary.
* You can't work around it, as you cannot tell MFC not to report this
false memleaks and use the CRT mechanism instead.
* You can't work around it, as your main application needs to use MFC.
* You can't work around it, as the 3rd party DLL cannot, in general, be
made to link against MFC (thereby forcing a later unload of mfc80ud.dll)
* You can't even ignore the MFC dump and additionally use the CRT dump
as MFC will switch it off after it dumped!
Bah!
So ... I'm stuck with a program that dumps 2000 memory leaks at
MFC-cleanup that are false and will obscure any real (and possibly
problematic) memleaks I would like to find ...
It would be interesting to hear from someone who knows a rational behind
the MFC code or has some general thoughts how to get around it or to
hear why I'm completely mistaken :)
cheers,
Martin
On Friday, July 11, 2008 9:45 AM
Carl Daniel [VC++ MVP] wrote:
Martin T.
Martin T. wrote:
Actually, you probably can - If you call LoadLibrary on the MFC DLL
yourself, that should push it to the back of the unload order since it is
refcount will not go to zero.
-cd
On Friday, July 11, 2008 12:34 PM
Doug Harrison [MVP] wrote:
Re: Why does MFC call _CrtDumpMemoryLeaks ?!?
On Fri, 11 Jul 2008 15:28:23 +0200, "Martin T." <***@gmx.at> wrote:
The rationale is that it was a mistake. (The real question is, "Why won't
they fix it?") For a workaround for those non-MFC DLLs you mentioned, see
if these threads help:
http://groups.google.com/group/microsoft.public.vc.debugger/msg/6b90e68f21529e56
http://groups.google.com/group/microsoft.public.vc.mfc/browse_frm/thread/73493ddec165a5cb/e651b944da9c619d?#e651b944da9c619d
Though I never tried it, the second one should help with those DLLs you
can't modify.
--
Doug Harrison
Visual C++ MVP
On Monday, July 14, 2008 3:55 AM
Martin T. wrote:
Re: Why does MFC call _CrtDumpMemoryLeaks ?!?
Doug Harrison [MVP] wrote:
I think this actually is a relly big question, especially with the noise
Microsoft made with the "MFC Update Powered By BCGSoft" / "... the
Visual C++ team decided to reinvest in MFC ..."
Since people are working on it anyways, fix it fcs!
(Haven't tried it with VS 2008.)
Thank you, thank you, thank you :-)
I really can't think why that thread never turned up in my google
searches, esp. since I tried to solve this problem twice during the last
few months. (I guess I haven't google'd groups after I found the
_AFX_DEBUG_STATE code, though)
http://groups.google.com/group/microsoft.public.vc.mfc/browse_frm/thread/73493ddec165a5cb/e651b944da9c619d?#e651b944da9c619d
really solves the problem.
Might I add two points:
* On my Visual Studio 2005 I have to use a symbol from the DLL I create
to hold the MemoryLeakDetector object or otherwise the linker will not
load the DLL.
* I have added trace messages to to the ctor and dtor of the class:
_RPT0(_CRT_WARN, "== MemoryLeakDetector ==\n");
Allow me to re-post the code below and confirm that this is indeed
working with Visual Studio 2005.
cheers,
Martin
[ HEADER ]
IGNORE_MFC_LEAKS_API int use_ignore_mfc_leaks(void);
[ CPP ]
// ignore_mfc_leaks.cpp : Defines the entry point for the DLL application.
//
// Dummy function to make sure the DLL is loaded:
IGNORE_MFC_LEAKS_API int use_ignore_mfc_leaks(void)
{
return 0;
}
static _CRT_REPORT_HOOK prevHook;
static bool SwallowReport;
class MemoryLeakDetector
{
public:
MemoryLeakDetector();
virtual ~MemoryLeakDetector();
};
int ReportingHook( int reportType, char* userMessage, int* retVal );
MemoryLeakDetector::MemoryLeakDetector()
{
_RPT0(_CRT_WARN,
"===============MemoryLeakDetector=====================\n");
//don't swallow assert and trace reports
SwallowReport = false;
//change the report function
prevHook = _CrtSetReportHook(ReportingHook);
}
//this destructor is called after mfc has died
MemoryLeakDetector::~MemoryLeakDetector()
{
//make sure that there is memory leak detection at the end of the program
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) |
_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF);
//reset the report function to the old one
_CrtSetReportHook(prevHook);
_RPT0(_CRT_WARN, "=============== ~
MemoryLeakDetector=====================\n");
}
static MemoryLeakDetector MLD; //this lives as long as this translation
unit
int ReportingHook( int reportType, char* userMessage, int* retVal )
{
//_CrtDumpMemoryLeaks() outputs "Detected memory leaks!\n" and calls
//_CrtDumpAllObjectsSince(NULL) which outputs all leaked objects,
//ending this (possibly long) list with "Object dump complete.\n"
//In between those two headings I want to swallow the report.
if ((strcmp(userMessage,"Detected memory leaks!\n") == 0) ||
SwallowReport) {
if (strcmp(userMessage,"Object dump complete.\n") == 0)
SwallowReport = false;
else
SwallowReport = true;
return true; //swallow it
}
else
return false; //give it back to _CrtDbgReport()
};
On Monday, July 14, 2008 3:59 AM
Martin T. wrote:
Re: Why does MFC call _CrtDumpMemoryLeaks ?!?
Carl Daniel [VC++ MVP] wrote:
I have tried calling LoadLibrary(_T("mfc80ud.dll")); and
LoadLibrary(_T("mfc80DEU.dll")); in main() but the MFC DLL still will be
unloaded before a user-supplied statically linked DLL.
cheers,
martin
On Monday, July 14, 2008 12:18 PM
Doug Harrison [MVP] wrote:
Re: Why does MFC call _CrtDumpMemoryLeaks ?!?
Google Groups search has been on the fritz for a long, long time now. it is
incomplete and inconsistent.
--
Doug Harrison
Visual C++ MVP
On Tuesday, June 30, 2009 1:20 AM
Rixio wrote:
Default Memory Leak detection in MSVC 2008
You are required to be a member to post replies. After logging in or becoming a member, you will be redirected back to this page.
Submitted via EggHeadCafe - Software Developer Portal of Choice
EggHeadCafe Chat Chaos in Silverlight Released Today
http://www.eggheadcafe.com/tutorials/aspnet/325ea67e-d6c4-4811-b096-54f31bdede5d/eggheadcafe-chat-chaos-in.aspx