views:

511

answers:

4

Hi!

I try to follow this article: http://flipcode.com/archives/How%5FTo%5FFind%5FMemory%5FLeaks.shtml

to overload my new and delete functions in order to track memory leaks.

however - if i try to compile, I get a

C2365: "operator new": redefinition; previous definition was a "function"

in the file xdebug

xdebug gets included in xlocale - however, i can't find where my project is including xlocale

I'm using MFC for multithreading in my project.

Can someone tell me how i can get my memory leak tracking to work?

Thanks!

//edit: So this is my findMemoryLeak.h which i include in the end of stdafx.h

#ifndef _FINDMEMORYLEAK_H
#define _FINDMEMORYLEAK_H

#include <list>
using namespace std;

#ifdef _DEBUG

typedef struct {
 DWORD address;
 DWORD size;
 char file[64];
 DWORD line;
} ALLOC_INFO;

typedef list<ALLOC_INFO*> AllocList;

AllocList *allocList;

void AddTrack(DWORD addr,  DWORD asize,  const char *fname, DWORD lnum)
{
 ALLOC_INFO *info;

 if(!allocList) {
  allocList = new(AllocList);
 }

 info = new(ALLOC_INFO);
 info->address = addr;
 strncpy(info->file, fname, 63);
 info->line = lnum;
 info->size = asize;
 allocList->insert(allocList->begin(), info);
};

void RemoveTrack(DWORD addr)
{
 AllocList::iterator i;

 if(!allocList)
  return;
 for(i = allocList->begin(); i != allocList->end(); i++)
 {
  if((*i)->address == addr)
  {
   allocList->remove((*i));
   break;
  }
 }
};


void DumpUnfreed()
{
 AllocList::iterator i;
 DWORD totalSize = 0;
 char buf[1024];

 if(!allocList)
  return;

 for(i = allocList->begin(); i != allocList->end(); i++) {
  sprintf(buf, "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d unfreed\n",
   (*i)->file, (*i)->line, (*i)->address, (*i)->size);
  OutputDebugString(buf);
  totalSize += (*i)->size;
 }
 sprintf(buf, "-----------------------------------------------------------\n");
 OutputDebugString(buf);
 sprintf(buf, "Total Unfreed: %d bytes\n", totalSize);
 OutputDebugString(buf);
};


inline void * __cdecl operator new(unsigned int size, const char *file, int line)
{
 void *ptr = (void *)malloc(size);
 AddTrack((DWORD)ptr, size, file, line);
 return(ptr);
};

inline void __cdecl operator delete(void *p)
{
 RemoveTrack((DWORD)p);
 free(p);
};

inline void * __cdecl operator new[](unsigned int size, const char *file, int line)
{
 void *ptr = (void *)malloc(size);
 AddTrack((DWORD)ptr, size, file, line);
 return(ptr);
};

inline void __cdecl operator delete[](void *p)
{
 RemoveTrack((DWORD)p);
 free(p);
};
#endif

//make the normal new function call the new function with three parameters
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#else
#define DEBUG_NEW new
#endif
#define new DEBUG_NEW


#endif

when I include it like this in the end of stdafx.h, i get thousands of compilererrors, most of them in either xdebug or xlocale, with the first being

C2365: "operator new": redefinition; previous definition was a "function"

in xdebug on line 32

A: 

In Visual Studio, debug builds of programs already use a 'debug heap', so your own instrumentation is unnecessary.

Using the debug features of your platform, you could for example call _CrtDumpMemoryLeaks at the end of your program, without actually overloading everything.

Will
Hi and thanks for the answer!But the overloaded methods described in the article are much better. _CrtDumpMemoryLeaks just returns true if a memory leak occurred, using the technique described in the article one should be able to identify exactly what allocations don't get freed again, in what file, on what line.is there also a _Crt function provided that does this? if not, how can I get my own overrided new/delete functions to work?
Mat
The leak info is printed to stderr so you'll see it in visual studio. It also finds leaks that are not just caused by object news and deletes, such as you not managing win32 c-API resources and such.
Will
Thanks again! But this is outputting hundredthousands of lines of stuff like "{692972} normal block at 0x038A1480, 12 bytes long. Data: < H > 80 14 8A 03 48 0A 8A 03 B0 86 E0 02". That's not useful for me.. all i want to know is on what line of my code I call a 'new' which does not get deleted later on
Mat
You don't know that its a object allocated with 'new'.What you can do is set the hooks for the malloc/realloc/free; that'll catch all your allocs, but not those inside libraries you call.
Will
On Linux, Valgrind would be just the thing! In the windows world, Purify is a commercial equivilent.
Will
Is there no way to get my own overloaded new/delete to work?
Mat
Without seeing your code, I can't tell if you have a simple syntax error or two dueling definitions. You could try using /E to get preprocessor output to see if you have picked up a definition in a header file somehow. You could post your actual code ...In other words, YES YOU CAN make this work, but you haven't posted enough information to sort out your problem.
bmargulies
I added the code i include in my stdafx.h in the end - it's actually exaclty the same code as described in the article
Mat
+1  A: 

to find where xlocale is getting included. just changethe name of xlocale to something else. try to compile and you will see where it fails

jojo
A: 

You are defining the very same overload that Microsoft defines for their own debugging, and running into theirs. I recommend adding an extra dummy parameter to your operator.

I also recommend debugging this not in stdafx.h before putting it there.

bmargulies
A: 

Trying to debug this way with std lib is not really going to work out. It won't catch all (or any) of the memory allocation. It's just one of a million reasons not to use std lib, stl, or boost.

Charles Eli Cheese