|
Intead of calling
_CrtDumpMemoryLeaks() at the program exit, call
_CrtSetDbgFlag(_crtDbgFlag | _CRTDBG_LEAK_CHECK_DF); at the program start instead.
There is a long global vars termination routine runs after main or WinMain exit. Once that routine finishes it will call _CrtDumpMemoryLeaks() automatically.
modified 16-Aug-12 20:23pm.
|
|
|
|
|
This is what I get:
Detected memory leaks!
Dumping objects ->
{57} normal block at 0x003B31D8, 2 bytes long.
Data: < > 00 00
{55} normal block at 0x003B3158, 2 bytes long.
Data: < > 00 00
{54} normal block at 0x003B3118, 2 bytes long.
Data: < > 00 00
Object dump complete.
This is with a windows win32 program. Any idea?
|
|
|
|
|
I get similar results. An earlier post suggests the new "new" is not getting called. Maybe that's what is happening.
-Steve
|
|
|
|
|
Hi all,
I'll preface this by saying I tried out this code on a small application to test it out and it works a treat!
However, I've tried using it into a large program written by someone else, who has asked me to maintain the code, and I get a lot of compiler errors and warnings.
<br />
warning C4291: 'void *__cdecl operator new(unsigned int,const char *,int)' : no matching operator delete found; memory will not be freed if initialization throws an exception<br />
Appears for every single time the new operator is called (which is a lot of times!).
Secondly, I get errors appearing like this one:
<br />
c:\program files\microsoft visual studio\vc98\include\fstream(217) : error C2059: syntax error : '&'<br />
c:\program files\microsoft visual studio\vc98\include\fstream(213) : while compiling class-template member function 'void __thiscall std::basic_filebuf<char,struct std::char_traits<char> >::_Init(struct _iobuf *,enum std::basic_filebuf<char,<br />
The line in question in fstream is
new (&_Loc) locale;
which clearly says it must be something wrong with my overloaded new operator.
Every CPP file in this program only uses the one header file, although that header file does call several other header files as well. I've included the
<br />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
at the very bottom of the main header file.
I don't need to be told how bad a practice it is of having ALL the source read out of the same header file. I'm just maintaining this code, I didn't write it.
Please help. Finding the source of the memory leaks without this is going to be damn near impossible.
|
|
|
|
|
Ooops, sorry, I got a bit excited and forgot to close my code tags.
|
|
|
|
|
just as an experiment, what happens if you put that #ifdef... block in each .cpp individually, and not include it in the global header ?
Cleek | Image Toolkits | Thumbnail maker
|
|
|
|
|
Hmm, that seemed to at least solve the errors in the fstream libraries. I still get the warnings though.
|
|
|
|
|
Just out of curiosity here, why would using a master header file would be a bad practice?
|
|
|
|
|
Hello,
If you have several projects in your solution or just a lot of files, try adding a space to the header and do a build. Suddenly, your space changed the build button to rebuild solution!
This is only a big problem in large solutions since it increadably increases the build times.
Behind every great black man...
... is the police. - Conspiracy brother
Blog[^]
|
|
|
|
|
Hello, all
I made a empty Dialog-based project, only append following info in xxxDlg.h:
"#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>"
and following info in OnInitDialog() of xxxDlg.cpp:
"_CrtDumpMemoryLeaks();"
When i debug, following info occured:
"Detected memory leaks!
Dumping objects ->
strcore.cpp(118) : {66} normal block at 0x009D4F50, 45 bytes long.
Data: < MS S> 01 00 00 00 0D 00 00 00 20 00 00 00 4D 53 20 53
Object dump complete."
Where is my memory leak from?
Could someone help me?Thx.
With Best Regards
Redeagle
2005.02.26
|
|
|
|
|
That's something related to CString class.
Be careful though that when using MFC, you don't need to _explicitly_ call _CrtDumpMemoryLeaks. It's being automatically called by the framework. Also when using MFC you don't need to do what this article is describing.
That function (_crtDump...) will dump all the allocated (and never freed) memory up to a point. Using the term "leaks" in the MSDN article describing the function is misleading.
So if you call it in OnInitDialog you'll just get a list of dynamically allocated blocks up to that point.
|
|
|
|
|
I've changed your leakwatcher and removed the THIS_FILE:
now i only have to include the leakwatcher.
#ifndef DE_C_LEAKWATCHER_H
#define DE_C_LEAKWATCHER_H
#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(__FILE__, __LINE__)
#define MALLOC_DBG(x) _malloc_dbg(x, 1, THIS_FILE, __LINE__);
#define malloc(x) MALLOC_DBG(x)
#endif // _DEBUG
#endif // #include guard
#ifdef _DEBUG
#define new DEBUG_NEW
//#undef THIS_FILE
//static char THIS_FILE[] = __FILE__;
#endif
|
|
|
|
|
Hello,
I guess that the correct place is at the end of the InitInstance method.. but even so, a memory-leak is detected due that not all memory is freed yet. (I just tested with an empty dialog application)
Where is the correct place to put the _CrtDumpMemoryLeaks() on a MFC Dialog application?
Any hint?
--- Ricky.
-- Ricky Marek (AKA: rbid)
-- "Things are only impossible until they are not" --- Jean-Luc Picard
|
|
|
|
|
I'm attempting to use the original code, but naturally, I have a problem. My header1.h file #includes header2.h file. They both hold class definitions because they're template classes and I'm using VC++ 6.0. Thus they have no .cpp counterparts. This is in header1.h:
// Header1.h includes
#include <header2.h>
#include <memleakfile.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
I'm getting an error of THIS_FILE having being defined already, because header2.h has the same code. I presume if it was the usual .cpp usage, the 'static' keyword would ensure one wouldn't have this problem. Any way to solve this?
I tried substituting #define THIS_FILE __FILE__. If I remember correctly, macros don't expand within macros, and that's why this won't work.
I suppose I could avoid using a separate .h file, and just dump this code into every file:
inline void* operator new(size_t nSize, const char * lpszFileName, int nLine)
{
return ::operator new(nSize, 1, lpszFileName, nLine);
}
inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine)
{
::operator delete(_P, _NORMAL_BLOCK, lpszFileName, nLine);
}
#define new new(__FILE__, __LINE__)
#define MALLOC_DBG(x) _malloc_dbg(x, 1, __FILE__, __LINE__);
#define malloc(x) MALLOC_DBG(x)
Incidently, I don't understand #undef THIS_FILE. Doesn't this only affect the preprocessor, which has nothing to do with the static char THIS_FILE[] = __FILE__; line?
Thanks
|
|
|
|
|
I'm replying 'cause I can't edit...
"I tried substituting #define THIS_FILE __FILE__. If I remember correctly, macros don't expand within macros, and that's why this won't work."
That's rubbish. I just tried it and it worked. This is what I get though when I try it:
d:\program files\microsoft visual studio\vc98\include\new(35) : error C2059: syntax error : 'string'
d:\program files\microsoft visual studio\vc98\include\new(35) : error C2091: function returns function
d:\program files\microsoft visual studio\vc98\include\new(35) : error C2809: 'operator new' has no formal parameters
d:\program files\microsoft visual studio\vc98\include\new(36) : error C2059: syntax error : 'string'
d:\program files\microsoft visual studio\vc98\include\new(37) : error C2091: function returns function
d:\program files\microsoft visual studio\vc98\include\new(37) : error C2556: 'void *(__cdecl *__cdecl operator new(void))(unsigned int,const struct std::nothrow_t &)' : overloaded function differs only by return type from 'void *(__cdecl *__cdecl op
erator new(void))(unsigned int)'
d:\program files\microsoft visual studio\vc98\include\new(35) : see declaration of 'new'
d:\program files\microsoft visual studio\vc98\include\new(41) : error C2059: syntax error : 'string'
d:\program files\microsoft visual studio\vc98\include\new(42) : error C2091: function returns function
d:\program files\microsoft visual studio\vc98\include\new(42) : error C2556: 'void *(__cdecl *__cdecl operator new(void))(unsigned int,void *)' : overloaded function differs only by return type from 'void *(__cdecl *__cdecl operator new(void))(unsig
ned int)'
d:\program files\microsoft visual studio\vc98\include\new(35) : see declaration of 'new'
d:\program files\microsoft visual studio\vc98\include\new(42) : error C2809: 'operator new' has no formal parameters
d:\program files\microsoft visual studio\vc98\include\new(42) : error C2065: '_P' : undeclared identifier
I only get this when I try to use header1.h, or any other header file. If I just have the code in main.cpp, it doesn't give any errors, and works fine.
|
|
|
|
|
Anonymous wrote:
I'm getting an error of THIS_FILE having being defined already
THIS_FILE is just a variable like any other.
because you're nesting #includes, it as if you're doing this:
int foo;
...
int foo;
...
int foo;
one solution might be to use #include guards around your code:
#ifndef MYALLOCATIONFUNCTIONS
#define MYALLOCATIONFUNCTIONS
... all the code in your header1.h file
#endif
-c
ClickPic | ImgSource | CheeseWeasle
|
|
|
|
|
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...
#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 />
static char THIS_FILE[] = __FILE__;<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 />
#include <debug_crt.h><br />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
<br />
void GenerateMemoryLeak ()<br />
{<br />
int *l = new int;<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_
#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.
P.S. I still don't understand that #undef THIS_FILE...
Cheers
|
|
|
|
|
Same Anonymous poster here. A correction to the previous post:
One may have noticed that the
#if !defined(_HEADER1_H_)<br />
#define _HEADER1_H_<br />
...<br />
#endif // _HEADER1_H_
was around the main.cpp code instead of header1.h code.
It makes no difference fixing it.
I know why I'm getting the errors I'm getting, I need a way around them. I've tried this method of catching memory leaks using a .cpp file instead of a .h and it works fine, because one never has a .cpp file include another (or a good reason for doing so, at least).
As I've said before, I need to have everything in the .h file because I'm using template classes and VC++ 6.0 SP5. I could have the definitions in a separate a .cpp file, and #include it at the end of the .h file, but that's effectively the same thing, and won't solve the problems I'm having.
Thanks for any help with this problem!
|
|
|
|
|
take all that THIS_FILE stuff out of your header. it's a variable declaration, and you shouldn't declare variables in header files (for just this reason).
header files aren't expanded like macros, they're read and stuffed into the .cpp file whole, at the plaec of the #include. so, when you have this in and #included header:
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
and the same thing in the .cpp that #includes the header, you end up with:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
...
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
and then when the preprocessor gets done with the #ifdefs, you end up with:
<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
<br />
...<br />
<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
which is equivalent (in terms of error) to this:
<br />
int foo;<br />
int foo;<br />
you've declared the same variable twice.
Anonymous wrote:
I still don't understand that #undef THIS_FILE
it's just something that the normal new/malloc stuff used. i just copied it into my stuff. i didn't bother to figure out what it does. but, i'm 99.44% sure it's not the problem here.
ClickPic | ImgSource | CheeseWeasle
|
|
|
|
|
"...you've declared the same variable twice"
Yup. I understand all of that completely. And I'm not just saying that! The end result is that you can't use this method of getting memory leaks and their origin, in header files. You can only use it in source (.cpp) files because of the problem you have just above described.
I was asking for any way around the problem, i.e. how to get this working for header files. I guess there just isn't one!
class MyClass<br />
{<br />
public:<br />
MyClass () {}<br />
~MyClass () {}<br />
<br />
void GenerateMemoryLeak ()<br />
{<br />
int *l = new int;
}<br />
};
In other words, you can't spot the above memory leak using this method as is, because the leaking code is in a .h file with no .cpp file. Why would I have code like that? Because template classes need it so. A quick google found me this: www.chesapeake.edu/malone/CSC220/VisC++Problem.PDF[^] talks about it just in case some need a reminder...
Thanks for your assistance, regardless!
|
|
|
|
|
this works for me, in simple tests:
header:
<br />
#ifndef IMWATCHINGYOULEAK<br />
#define IMWATCHINGYOULEAK<br />
<br />
#include < crtdbg.h ><br />
<br />
#ifdef _DEBUG<br />
void* operator new(size_t nSize, const char * lpszFileName, int nLine)<br />
{<br />
return ::operator new(nSize, 1, lpszFileName, nLine);<br />
}<br />
#define DEBUG_NEW new(THIS_FILE, __LINE__)<br />
<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 />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#define THIS_FILE __FILE__<br />
#endif<br />
<br />
template < class T > class leaky<br />
{<br />
public:<br />
void leakbytes(int i) <br />
{<br />
char * p = new char[i];
}<br />
};<br />
#endif // #include guard<br />
and then this is my .cpp file:
<br />
#include "stdafx.h"<br />
#include "lw.h"<br />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
<br />
int main(int argc, char* argv[])<br />
{<br />
printf("Hello World!\n");<br />
<br />
leaky < int > bob;<br />
bob.leakbytes(100); <br />
<br />
int *foo = new int[1000];
<br />
_CrtDumpMemoryLeaks(); <br />
return 0;<br />
} <br />
ClickPic | ImgSource | CheeseWeasle
|
|
|
|
|
Aha! All problems solved!
At first I wasn't using an ultra simple project to test it on, merly a simple one. Note in my first post I said:
"...I tried substituting #define THIS_FILE __FILE__. ..."
In the post immediatly after that, dated 23:23 5 Jan '04 as far as I can see, I list a whole host of errors that I got when I tried it. They didn't make a whole lot of sense to me (and I've using VC++ for a long while now), so I assumed it was some macro complication.
I've found out now that they cropped up not because they were caused by the #define THIS_FILE __FILE__, but rather they were just 'revealed' because the #define fix succeeded, and allowed compilation to get to them...
I've been tinkering with an ultra simple project since, and because your suggested use of the #define fix worked in the ultra simple project and not in the simple project, I wanted to know why...
Long storey slightly shorter, those errors in the 'new' file cropped up because the order of the includes in main.cpp was:
#include "header1.h"<br />
#include <iostream><br />
#include <debug_crt.h>
I remember you advising in the article to place the debug_crt.h (in my case) after all previous #includes. Well that #include < iostream > (which wasn't in the ultra simple project) effectively isn't before it, because header1.h contains debug_crt.h and of course it is before debug_crt.h.
I'm not quite sure of the whys, or the exact causes for the errors, all I know is:
#include < iostream ><br />
#include "header1.h"<br />
#include < debug_crt.h >
Fixes 'em!
P.S. sometimes one needs to do a 'rebuild all', VC++ sometimes doesn't do a build normally. I'm getting 'operator DEBUG_NEW not recognized' errors, for example. I'm not sure if it's the .h files with declarations and definitions, or not...
Many thanks for the assist!
|
|
|
|
|
Curses! Just a typo fix in my previous post:
#include "header1.h"
#include
#include
should be
#include "header1.h"
#include < iostream >
#include < debug_crt.h >
At first, I thought those spaces between < and > were just odd coding style... : \
|
|
|
|
|
The specialized "void* operator new(size_t nSize, const char * lpszFileName, int nLine)" is never called--the global operator "new (size_t)" is always called.
|
|
|
|
|
I have tried to add the code and compile, but I get linker errors. It appears that I get one for each source file in which new is used.
Any help would be appreciated.
Frame.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
Offsets.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
RMDCView.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
RtmsView.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
StdAfx.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
Str.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
TraficonView.obj : error LNK2005: "void * __cdecl operator new(unsigned int,char const *,int)" (??2@YAPAXIPBDH@Z) already defined in FMDB.obj
..\OlympicMapAux\EXE\OlympicMap_Debug.exe : fatal error LNK1169: one or more multiply defined symbols found
|
|
|
|
|