Click here to Skip to main content
15,860,859 members
Articles / Desktop Programming / MFC
Article

Detailed memory leak dumps from a console app

Rate me:
Please Sign up or sign in to vote.
4.79/5 (16 votes)
21 May 20021 min read 202.9K   57   45
How to get path and line number info for memory leaks, in a console app

Introduction

Finding memory leaks in a non-MFC app can be difficult because the debugger doesn't display path and line number info in the debug window. But, it's quite easy to enable that info. Here's how:

Step 1

Copy this to a file called LeakWatcher.h

#ifndef IMWATCHINGYOULEAK
#define IMWATCHINGYOULEAK

#include <crtdbg.h>

#ifdef _DEBUG
void* operator new(size_t nSize, const char * lpszFileName, int nLine)
{
    return ::operator new(nSize, 1, lpszFileName, nLine);
}
#define DEBUG_NEW new(THIS_FILE, __LINE__)

#define MALLOC_DBG(x) _malloc_dbg(x, 1, THIS_FILE, __LINE__);
#define malloc(x) MALLOC_DBG(x)

#endif // _DEBUG

#endif // #include guard

Step 2

Call _CrtDumpMemoryLeaks(); at the end of your program (or wherever you want to see outstanding memory allocations).

Steps 3...N

Add this to each of your source files (after your last #include) :

#include "LeakWatcher.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

What does it do?

This does the same thing an MFC app does - it provides the path and line number of each allocation to the C-runtime allocation routines. Those routines store the path and line number for each allocation, and spit them out when you call _CrtDumpMemoryLeaks();. You should recognize that little chunk of code in step 3 from every source file that the AppWizard (and ClassWizard, mostly) has ever created.

Why not just use _CRTDBG_MAP_ALLOC?

#define _CRTDBG_MAP_ALLOC will provide file/line info for leaks caused by malloc, but for leaks with new, it ends up telling you that the leak occurred in crtdbg.h (because that's where MS defined their new) - not really useful.

Credits

This represents about ten minutes of searching through Microsoft's C runtime and MFC source files. So, all of the credit goes to MS. But, all of the blame goes to MS, too, for not making this part of the non-MFC headers. Anyway, have fun and be excellent to each other.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
United States United States
Chris Losinger was the president of Smaller Animals Software, Inc. (which no longer exists).

Comments and Discussions

 
AnswerBetter way to avoid unfiled and unlided memory leaks is to Pin
steveb16-Aug-12 14:04
mvesteveb16-Aug-12 14:04 
GeneralHit or Miss on the line number reporting... Pin
heckknow24-Dec-06 11:54
heckknow24-Dec-06 11:54 
GeneralRe: Hit or Miss on the line number reporting... Pin
gameengineer15-Mar-07 10:16
gameengineer15-Mar-07 10:16 
GeneralTwo Problems Pin
Andrew Nosworthy4-May-05 21:36
Andrew Nosworthy4-May-05 21:36 
GeneralRe: Two Problems Pin
Andrew Nosworthy4-May-05 21:37
Andrew Nosworthy4-May-05 21:37 
GeneralRe: Two Problems Pin
Chris Losinger5-May-05 0:59
professionalChris Losinger5-May-05 0:59 
GeneralRe: Two Problems Pin
Andrew Nosworthy5-May-05 13:34
Andrew Nosworthy5-May-05 13:34 
GeneralRe: Two Problems Pin
Nosferatus22-Jul-05 5:53
Nosferatus22-Jul-05 5:53 
GeneralRe: Two Problems Pin
Bob Stanneveld1-Feb-06 21:15
Bob Stanneveld1-Feb-06 21:15 
QuestionWhere is memory leak from? Pin
morntide25-Feb-05 16:05
morntide25-Feb-05 16:05 
AnswerRe: Where is memory leak from? Pin
Nosferatus22-Jul-05 5:59
Nosferatus22-Jul-05 5:59 
Questionisn't this better? Pin
Anonymous2-Feb-05 0:17
Anonymous2-Feb-05 0:17 
GeneralWhere to put _CrtDumpMemoryLeaks() for Dialog based applications... Pin
rbid21-Dec-04 21:16
rbid21-Dec-04 21:16 
GeneralTHIS_FILE redefinition Problems Pin
Anonymous5-Jan-04 16:37
Anonymous5-Jan-04 16:37 
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous5-Jan-04 17:23
Anonymous5-Jan-04 17:23 
GeneralRe: THIS_FILE redefinition Problems Pin
Chris Losinger6-Jan-04 1:32
professionalChris Losinger6-Jan-04 1:32 
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous6-Jan-04 14:14
Anonymous6-Jan-04 14:14 
As a matter of course, I use that...

#ifndef MYHEADERFILE
#define MYHEADERFILE

... all the code in your header1.h file
#endif

...trick.

I don't like giving huge code dumps, but it's a tiny program...

// main.cpp<br />
#if !defined(_HEADER1_H_)<br />
	#define	_HEADER1_H_<br />
<br />
#include "header1.h"<br />
#include <debug_crt.h><br />
<br />
#ifdef _DEBUG<br />
	#define new DEBUG_NEW<br />
	#undef THIS_FILE<br />
<br />
	//#if !defined(_THIS_FILE_DEFINED_)<br />
		//#define _THIS_FILE_DEFINED_<br />
		static char THIS_FILE[] = __FILE__;<br />
	//#endif<br />
#endif<br />
<br />
int main ()<br />
{<br />
	SetMemoryLeakFlag ();<br />
<br />
	GenerateMemoryLeak ();<br />
<br />
	int *l = new int;<br />
<br />
	return 0;<br />
}<br />
<br />
#endif	// _HEADER1_H_


<br />
// header1.h<br />
#include <debug_crt.h><br />
<br />
#ifdef _DEBUG<br />
	#define new DEBUG_NEW<br />
	#undef THIS_FILE<br />
<br />
	//#if !defined(_THIS_FILE_DEFINED_)<br />
		//#define _THIS_FILE_DEFINED_<br />
		static char THIS_FILE[] = __FILE__;<br />
	//#endif<br />
#endif<br />
<br />
void GenerateMemoryLeak ()<br />
{<br />
	int *l = new int;<br />
}



// debug_crt.h<br />
#if !defined(_DEBUG_CRT_H_)<br />
	#define	_DEBUG_CRT_H_<br />
<br />
#include <cstdlib><br />
#include <crtdbg.h><br />
<br />
#ifdef _DEBUG<br />
<br />
		inline void* operator new(size_t nSize, const char * lpszFileName, int nLine)<br />
		{<br />
			return ::operator new(nSize, 1, lpszFileName, nLine);<br />
		}<br />
<br />
		inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine) <br />
		{ <br />
			::operator delete(_P, _NORMAL_BLOCK, lpszFileName, nLine); <br />
		}<br />
<br />
		#define DEBUG_NEW new(THIS_FILE, __LINE__)<br />
		#define MALLOC_DBG(x) _malloc_dbg(x, 1, THIS_FILE, __LINE__);<br />
		#define malloc(x) MALLOC_DBG(x)<br />
<br />
#endif	// _DEBUG<br />
<br />
void SetMemoryLeakFlag ();<br />
<br />
#endif	// _DEBUG_CRT_H_



// debug_crt.cpp<br />
#include <debug_crt.h><br />
<br />
void SetMemoryLeakFlag ()<br />
{<br />
	#ifdef _DEBUG<br />
		int tmpDbgFlag;<br />
<br />
		tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);<br />
		tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;<br />
		tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;<br />
<br />
		_CrtSetDbgFlag (tmpDbgFlag);<br />
	#endif<br />
}


That's the whole project. Main.cpp includes header1.h, and debug_crt.h. Also, header1.h and debug.cpp include debug_crt.h. If I have the _THIS_FILE_DEFINED_ lines commented out like above, it complains of THIS_FILE in header.h being redifined in main.cpp. Uncommenting that means it compiles, but there will only ever be one THIS_FILE. Meaning the first file the compiler finds it in will be blamed for any and all memory leaks! In this case, the memory leak in main.cpp gets pinned on header1.h. Frown | :(

P.S. I still don't understand that #undef THIS_FILE...

Cheers
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous6-Jan-04 14:40
Anonymous6-Jan-04 14:40 
GeneralRe: THIS_FILE redefinition Problems Pin
Chris Losinger6-Jan-04 14:53
professionalChris Losinger6-Jan-04 14:53 
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous7-Jan-04 3:11
Anonymous7-Jan-04 3:11 
GeneralRe: THIS_FILE redefinition Problems Pin
Chris Losinger7-Jan-04 3:39
professionalChris Losinger7-Jan-04 3:39 
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous7-Jan-04 4:34
Anonymous7-Jan-04 4:34 
GeneralRe: THIS_FILE redefinition Problems Pin
Anonymous7-Jan-04 4:39
Anonymous7-Jan-04 4:39 
Generalspecialized &quot;new&quot; is never called Pin
blizzymadden25-Nov-03 12:46
blizzymadden25-Nov-03 12:46 
GeneralLink Errors Pin
Christian Cheney19-Nov-02 5:59
Christian Cheney19-Nov-02 5:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.