|
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
|
|
|
|
|
does this app use MFC?
-c
A conclusion is simply the place where someone got tired of thinking.
|
|
|
|
|
"Not Using MFC" in project settings
|
|
|
|
|
does fmdb.cpp define it's own version of "new" ?
-c
A conclusion is simply the place where someone got tired of thinking.
|
|
|
|
|
|
I solved my problem using Mac's code from the "Excellent!" thread in place of the article code in LeakWatcher.h. It works well.
Thank you to Chris for producing the article and helping me out, and also to Mac for posting his variation.
|
|
|
|
|
I have the same situation with link errors - can you post a link to the posting from Mac
cheers Dave
|
|
|
|
|
I think the answer is to modify the header so the new operator is inlined. This avoids the multiple definition problems. This seems to work for me:
inline void* operator new(size_t nSize, const char * lpszFileName, int nLine)
{
return ::operator new(nSize, 1, lpszFileName, nLine);
}
I do still get warnings that there is no matching delete and there might be a problem if an exception is thrown during initialization, but it seems to work.
|
|
|
|
|
The reason is that the definition of the "new" operator
is beeing added to every .cpp file by including LeakWatcher.h
Modify LeakWatcher.h to contain the declaration only:
void* operator new(size_t nSize, const char * lpszFileName, int nLine);
and insert the definition directly into your main .cpp file (only one place):
#ifdef _DEBUG
void* operator new(size_t nSize, const char * lpszFileName, int nLine)
{
return ::operator new(nSize, 1, lpszFileName, nLine);
}
#endif
Dalibor
|
|
|
|
|
I have been trying to nail some memory leaks for a while, the only leak I saw is my patience was dripping until I read through the threads. With you guys' great codes I now can see the file, the line # and the paradise. Thanks Chris, thanks Rick, thanks anonymous...whoever you are
p.s. I'm programming wxWindows app using VC6 on Windows XP.
|
|
|
|
|
Hi,
In step 2, it's says:
Call _CrtDumpMemoryLeaks(); at the end of your program.
I have put it at the end of my WinMain function, but my global variables are deallocated after that. So, I always get a "fake" memory leak in my debug window. Did someone know how to fix that???
Thank in advance!!!
|
|
|
|
|
Create a class, and declare an object of the class global before the app object (I'm not quite sure where to declare it to make it the first constructed... you may want to create two classes, declaring one as a static object of the other. You could set up a test project to determine what types of objects are constructed first). Put the following in the constructor of the class.
int tmpDbgFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG );
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );
HTH
|
|
|
|
|
Ignore the 'tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;' line in the previous email. For some reason, it is causing my program to go into an infinite loop. Note also, that instead of including the above code in the constructor of your class, you could include _CrtDumpMemoryLeaks(); in the destructor.
|
|
|
|
|
First of all, thanks for the tips. They are very helpful.
I recently tried to use this code and it almost works but there are a few things I did to get it to work right for me with VC6.0. First, I had to add a delete operator. I get compiler errors without it. Here is the one I used :
<br />
<br />
__inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine)<br />
{<br />
::operator delete(_P, lpszFileName, nLine);<br />
}<br />
<br />
The rest of these are not necessarily required but they work nicely for me.
First, I did not need to use the MALLOC_DBG definition. The built-in one worked correctly as did the one for calloc.
Second, I use strdup frequently and there is no version of it that tracks allocations that I could find. Here is my version that will :
<br />
<br />
__inline char *StrDup( const char * string, const char * file, int line )<br />
{<br />
int length = strlen( string ) + 1;<br />
char *newstr = (char *)_malloc_dbg( length, _NORMAL_BLOCK, file, line );<br />
if( newstr )<br />
memcpy( newstr, string, length );<br />
return newstr;<br />
}<br />
<br />
#define strdup(string) StrDup(string,__FILE__,__LINE__)<br />
<br />
Thirdly, I use this little function as the first call in my programs :
<br />
<br />
__inline void SetMemDbgFlag( void )<br />
{<br />
#ifdef _DEBUG<br />
<br />
int tmp = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );<br />
tmp |= _CRTDBG_LEAK_CHECK_DF;
tmp &= ~_CRTDBG_CHECK_CRT_DF;
_CrtSetDbgFlag( tmp );<br />
<br />
#endif // _DEBUG<br />
}<br />
<br />
When the program terminates the CRTlib automatically checks for leaks and reports them correctly. I don't use any other Crt* calls.
Once again, thanks for the info. I found it very helpful.
|
|
|
|
|
I mean it really, but your code did not work at first for me (some errors and warnings C2491). So here is the code I am using now, greatly inspired by yours.
#ifdef _CRTDBG_MAP_ALLOC
#undef _CRTDBG_MAP_ALLOC
#endif
#include <crtdbg.h>
#ifdef _DEBUG
#define THIS_FILE __FILE__
inline void* operator new(size_t nSize, const char * lpszFileName, int nLine)
{
return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
}
inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine)
{
::operator delete(_P, lpszFileName, nLine);
}
#define DEBUG_NEW new(THIS_FILE, __LINE__)
#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, THIS_FILE, __LINE__)
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
#define _msize(p) _msize_dbg(p, _NORMAL_BLOCK)
#endif
I hope it helps.
Mac
|
|
|
|
|
Hi,
Using the code in the original posting gives me some linkage errors and the 4291 warning. Using the code shown in the 'Excellent' posting gives me the following:
warning C4717: 'operator delete' : recursive on all control paths, function will cause runtime stack overflow
PGAdoConnection.cpp
The file above is a wrapper to ADO that we use here.
Also, when I run my app through debug mode is shows some info, but no file names and line numbers.
Does anyone have any idea's why this might happen?
Thanks in advance.
|
|
|
|
|
gunnware wrote:
Using the code shown in the 'Excellent' posting gives me the following:
warning C4717: 'operator delete' : recursive on all control paths, function will cause runtime stack overflow
PGAdoConnection.cpp
Change :
inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine)
{
::operator delete(_P, lpszFileName, nLine);
}
To :
inline void __cdecl operator delete(void * _P, const char * lpszFileName, int nLine)
{
::operator delete(_P, _NORMAL_BLOCK, lpszFileName, nLine);
}
|
|
|
|
|
Nice.
Now what is the reason of #undef -ing _CRTDBG_MAP_ALLOC ?
I have a mixed application that uses legacy code and MFC. The legacy code is also uses in a non-MFC application.
Thanks in advance.
--- Rbid
|
|
|
|
|
You don't need to call _CrtDumpMemoryLeaks(),
just add #define _CRTDBG_MAP_ALLOC at your stdafx.h.
It is helpful for DLL etc.
Best Regards.
|
|
|
|
|
#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 "new") - not really useful.
-c
Cheap oil. It's worth it!
|
|
|
|
|
Chris you are indeed fast !!!
Cheers,
Joao Vaz
A person who is nice to you, but rude to the waiter, is not a nice person - Natalie Portman (Padme/Amidala of Star Wars)
|
|
|
|
|