Thread: Linking error with memory leak detection code. HELP!

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    4

    Linking error with memory leak detection code. HELP!

    This the code I'm having problems with. I took the code from an article over on flipcode (http://www.flipcode.com/tutorials/tut_memleak.shtml). I have placed the code in the stdafx.h file.

    Code:
    // Memory Debug code
    #ifndef DEBUG_NEW
    #ifdef _DEBUG
    #define DEBUG_NEW new(__FILE__, __LINE__)
    #else
    #define DEBUG_NEW new
    #endif
    #define new DEBUG_NEW
    
    
    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;
    
    	i = allocList->begin();
    	i == i;
    
    	if(!allocList)
    	{
    	    return;
    	}
    	for(i = allocList->begin(); !(i == allocList->end()); i++)
    	{
    	    if((*i)->address == addr)
    		{
    		    allocList->remove((*i));
    		    break;
    		}
    	}
    };
    
    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
    
    typedef struct 
    {
    	DWORD	address;
    	DWORD	size;
    	char	file[64];
    	DWORD	line;
    } ALLOC_INFO;
    
    typedef list<ALLOC_INFO*> AllocList;
    
    AllocList *allocList;
    
    
    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);
    };
    Right now, when I place the "DumpUnfreed" function in my destructor for the main class, I get these errors:

    Linking...
    StdAfx.obj : error LNK2005: "void __cdecl DumpUnfreed(void)" (?DumpUnfreed@@YAXXZ) already defined in Game.obj
    StdAfx.obj : error LNK2005: "class std::list<struct ALLOC_INFO *,class std::__default_alloc_template<1,0> > * allocList" (?allocList@@3PAV?$list@PAUALLOC_INFO@@V?$__defaul t_alloc_template@$00$0A@@std@@@std@@A) already defined in Game.obj
    Debug/Text Scrabble.exe : fatal error LNK1169: one or more multiply defined symbols found
    Error executing link.exe.

    Text Scrabble.exe - 3 error(s), 0 warning(s)

    I understand that dumpunfreed is getting defined multiple times, but I'm unsure how to stop that from happening and actually have the code compile and link. Any help would be greatly appreciated!

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What on earth are you trying to do? You do realize that 'new' is a reserved keyword in C++, right? So are you trying to overload it, or what exactly is your intent?
    #ifndef DEBUG_NEW
    #ifdef _DEBUG
    #define DEBUG_NEW new(__FILE__, __LINE__)
    #else
    #define DEBUG_NEW new
    #endif
    #define new DEBUG_NEW
    Does anyone else see a problem here, or is it just me?

    Quzah
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    4
    Yes, the code is trying to overload it, so that the overloaded functions get called. The functions add a track to the STL List for every allocation in the code, then removes the item from the list when it's deleted, and then when the program quits, it prints out what's left in the List (all the unfreed memory). Unfortunately, I didn't originall write the code, and I haven't had much experience with this kind of #ifdef's.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I have placed the code in the stdafx.h file.
    Don't *ever* change your compiler's headers unless you really know what you're doing. Make your own header and source file to link into the program instead.

    >I understand that dumpunfreed is getting defined multiple times
    Since you have this in a header, are you using inclusion guards to protect against multiple definitions? Judging from the code you've posted and your errors, I would guess that this is the problem.

    >Does anyone else see a problem here, or is it just me?
    It's just you. The code overloads new with two extra parameters. If _DEBUG is set then new calls the overload, otherwise the default new is used. This way the client program can always use new whether _DEBUG is defined or not.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Aug 2003
    Posts
    4
    Originally posted by Prelude
    >I have placed the code in the stdafx.h file.
    Don't *ever* change your compiler's headers unless you really know what you're doing. Make your own header and source file to link into the program instead.
    Stdafx isn't a compiler header, it's a header that's generated for every project. I didn't think it was that big a deal, but I can easily move it to it's own file.


    >I understand that dumpunfreed is getting defined multiple times
    Since you have this in a header, are you using inclusion guards to protect against multiple definitions? Judging from the code you've posted and your errors, I would guess that this is the problem.
    Inclusion guards like #ifndef H_File #define H_FILE #endif? Yea, that's already in the file, so I think I'm safe there. Originally I tried to put #ifndef DEBUG_NEW #endif around all the memory leak code. That gave me a compiler error and said that DumpUnfreed was an undeclared identifier. So I'm still swinging away, but can't seem to hit anything....anyone else have any suggestions?

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    161
    You shouldn't put function definitions in header files. In this case, you're including that header in two source files and each source file has a definition of that function. When your linker tries to link the two object files, it sees that each one has a function with the same signature (read: and with external linkage) and dies with a multiple definition error.

  7. #7
    Registered User
    Join Date
    Aug 2003
    Posts
    4
    Would someone mind trying to get this code to work? I'm totally at a loss. I moved the code to it's own file "mem.h, mem.cpp" and I got it to compile, but when I new something, my modified new operators never get called! I'm really at a loss here, any help would be greatly appreciated

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with shared memory shmdt() shmctl()
    By Jcarroll in forum C Programming
    Replies: 1
    Last Post: 03-17-2009, 10:48 PM
  2. memory leak in vector <int>
    By franziss in forum C++ Programming
    Replies: 21
    Last Post: 10-10-2006, 06:54 AM
  3. Replies: 2
    Last Post: 09-28-2006, 01:06 PM
  4. Memory Leak Help
    By (TNT) in forum Windows Programming
    Replies: 3
    Last Post: 06-19-2006, 11:22 AM
  5. Memory leak detection...
    By Devil Panther in forum Tech Board
    Replies: 6
    Last Post: 09-03-2005, 04:44 AM