Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

memory leak test at exit : here's a solution, any comments?

1,028 views
Skip to first unread message

Pieter Op de Beeck

unread,
May 12, 2000, 3:00:00 AM5/12/00
to
Hi,

Since nobody replied my earlier thread (-need help- in this ng and a
similar one in ..\debugger), I thought it would be usefull to give my
solution to the problem.

Remeber that MFC makes a call to _CrtDumpMemoryLeaks() in the
destructor of the _AFX_BEDUG_STATE, followed by _CrtSetDbgFlag()
which sets it to ~_CRTDBG_LEAK_CHECK_DF (therefor disabling memory
leak test at *true* program exit). Because the destructor is called
at exit (i.e. atexit()), but before statics residing in dlls are
destroyed, false memory leaks are reported. In my case this happened
in a lot (I.m using <iostream> in one of my dlls for one, but also
Imagemagick (image library) which is also using a few (big) statics).
This is actually no real problem. Except for the fact that I was
getting so many memory leak messages that I couldn't easily seperate
the false from the true ones. Anyway, a possible solution is to link
your application to a libray in which a static object is defined which
swallows the fals memory leak messages. It has to be in a library
because it should still be alive after MFC dies.

I put this into the headerfile :

#include <crtdbg.h>

static _CRT_REPORT_HOOK prevHook;
static bool SwallowReport;

class MemoryLeakDetector
{
public:
MemoryLeakDetector();
virtual ~MemoryLeakDetector();
};

int ReportingHook( int reportType, char* userMessage, int* retVal );


and this into the source :


#include "the header file"
#include <string.h>

MemoryLeakDetector::MemoryLeakDetector()
{
//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);

}

static MemoryLeakDetector MLD; //this lives as long as this file

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()
};


So, that's it. Link this to mfc and only true memory leaks are
reported.

Does anyone care to comment (better solution,...)?

Also, I was wondering, why did nobody answer my question (no hard
feelings, by the way): question too easy, question already answered a
million times, didn't see the problem, is there a problem?, take it
somewhere else, don't have an answer....

Friendly greeting,
Pieter Op de Beeck
K.U.Leuven - Belgium

Pieter Op de Beeck

unread,
May 12, 2000, 3:00:00 AM5/12/00
to
On Fri, 12 May 2000 12:27:31 GMT, pieter.o...@esat.kuleuven.ac.be
(Pieter Op de Beeck) wrote:

Actually, this line

>static MemoryLeakDetector MLD; //this lives as long as this file

should read :

static MemoryLeakDetector MLD; //this lives as long as this

translation unit


Doug Harrison

unread,
May 13, 2000, 3:00:00 AM5/13/00
to

>static MemoryLeakDetector MLD; //this lives as long as this file
>

>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()
>};
>
>
>So, that's it. Link this to mfc and only true memory leaks are
>reported.
>
>Does anyone care to comment (better solution,...)?

Very interesting! Thanks for posting this. My approach to reducing the
spurious leaks is to force my debug-mode DLLs that don't need MFC to
link to MFC anyway. This ensures they exit before MFC has a chance to
prematurely dump leaks. It doesn't do anything about false leaks in
the C++ runtime, however, and I routinely get a couple related to it,
which I've been able to live with. I'll have to give your method a
try.

>Also, I was wondering, why did nobody answer my question (no hard
>feelings, by the way): question too easy, question already answered a
>million times, didn't see the problem, is there a problem?, take it
>somewhere else, don't have an answer....

Well, this problem has been discussed frequently in the past, and
several times just in the last week. Also, experience has taught me to
reach for the "I" key in Agent when I run across threads titled "Need
help". More descriptive subjects don't have that effect!

--
Doug Harrison
d...@mvps.org
Visual C++ MVP

0 new messages