Jump to content
  • Advertisement
Sign in to follow this  
Greg K

Multiple Definitions

This topic is 4898 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If I have a file with: #ifndef MYFILE_H #define MYFILE_H class stuff #endif How could it possibly get defined more than once? Basically, I am trying to include a file called MemTracker.h in all my code files so that it can check for memory leaks. I can include it into a single file just fine, but as soon as I include it in more than one file it gives me a long list of multiple definitions, all within that one file. Does anyone know why this happens, or the solution to it? -Greg

Share this post


Link to post
Share on other sites
Advertisement
You can still only declare prototypes in a header, you can't create an object.
You need to use extern if you want to declare an object that can be accessed through the header.
The sentinals (the MYFILE_H stuff) only prevent you declaring structures and the like twice (Because the compiler thinks you're trying to give a different content to your structure).

Any chance of you posting your header here if it's not too big?

Share this post


Link to post
Share on other sites
Do you define any variables or create any instances in your header file? Those could trigger link errors, even with inclusion guards. Otherwise post the complete header file.

^^beaten

Share this post


Link to post
Share on other sites

#ifndef __MEMTRACKER_H__
#define __MEMTRACKER_H__

#include <cstdlib>
#include <string>
#include <list>
#include <bitset>
#include <iostream>
#include <iomanip>

#ifdef USE_MEMTRACKER

enum MemState { MS_ARRAY=0, MS_DELETED, MS_INC_DELETED };

class MemBlock
{
public:
MemBlock(size_t address, size_t size, const std::string &file, const std::string &func, size_t line, bool array) :
mAddress(address), mSize(size), mFile(file), mFunc(func), mLine(line)
{
mState[MS_ARRAY] = array;
}

size_t mAddress;
size_t mSize;
std::string mFile;
std::string mFunc;
size_t mLine;
std::bitset<3> mState;

friend std::ostream& operator<<(std::ostream &os, const MemBlock &block);
};

std::ostream& operator<<(std::ostream &os, const MemBlock &block)
{
return os << std::setw(9) << block.mSize << " bytes allocated at 0x" << std::ios::hex << block.mAddress
<< " in " << block.mFunc << " (" << block.mFile << ":" << std::setw(4) << block.mLine << ") "
<< (block.mState[MS_ARRAY]?"Array ":" ")
<< (block.mState[MS_DELETED]?"Deleted ":"LEAKED ")
<< (block.mState[MS_INC_DELETED]?"Incorrectly Deleted ":"");
}

class MemTracker
{
typedef std::list<MemBlock> BlockList;
typedef BlockList::iterator BlockIterator;

private:

static BlockList sMemBlocks;
static size_t sCurMem;
static size_t sMaxMem;

public:

static void newBlock(const MemBlock &block)
{
sMemBlocks.push_back(block);
sCurMem += block.mSize;
sMaxMem = std::max(sCurMem,sMaxMem);
}

static void deleteBlock(size_t address, bool arrayDelete)
{
for(BlockIterator it=sMemBlocks.begin(); it != sMemBlocks.end(); ++it)
{
if(it->mAddress == address)
{
sCurMem -= it->mSize;

if(it->mState[MS_ARRAY])
{
if(arrayDelete)
it->mState[MS_DELETED] = true;
else
it->mState[MS_INC_DELETED] = true;
}
else
{
if(!arrayDelete)
it->mState[MS_DELETED] = true;
else
it->mState[MS_INC_DELETED] = true;
}
}
}
}

static void showAllMem(std::ostream &os)
{
os << "--Memory Allocated--" << std::endl;
for(BlockIterator it=sMemBlocks.begin(); it != sMemBlocks.end(); ++it)
os << *it << std::endl;
}

static bool leaksExist()
{
for(BlockIterator it=sMemBlocks.begin(); it != sMemBlocks.end(); ++it)
{
if(!it->mState[MS_DELETED])
return true;
}
return false;
}

static void showLeaks(std::ostream &os)
{
os << "--Memory Leaked--" << std::endl;
for(BlockIterator it=sMemBlocks.begin(); it != sMemBlocks.end(); ++it)
{
if(!it->mState[MS_DELETED])
os << *it << std::endl;
}
}

static void showVitals(std::ostream &os)
{
os << "--Memory Report--" << std::endl
<< "Currently Allocated: " << std::setw(9) << sCurMem << " bytes" << std::endl
<< "Maximum Allocated: " << std::setw(9) << sMaxMem << " bytes" << std::endl;
}
};

MemTracker::BlockList MemTracker::sMemBlocks;
size_t MemTracker::sCurMem;
size_t MemTracker::sMaxMem;

inline void* operator new(size_t size, const char* file, const char* func, int line)
{
void *ptr = std::malloc(size);
MemTracker::newBlock(MemBlock((size_t)ptr, size, file, func, line, false));
return ptr;
}

inline void* operator new[](size_t size, const char* file, const char* func, int line)
{
void *ptr = std::malloc(size);
MemTracker::newBlock(MemBlock((size_t)ptr, size, file, func, line, true));
return ptr;
}

inline void operator delete(void* ptr)
{
MemTracker::deleteBlock((size_t)ptr, false);
std::free(ptr);
}

inline void operator delete[](void* ptr)
{
MemTracker::deleteBlock((size_t)ptr, true);
std::free(ptr);
}

#define DEBUG_NEW new(__FILE__, __FUNCTION__, __LINE__)
#define new DEBUG_NEW

#else //USE_MEMTRACKER

class MemTracker
{
public:
static void showAllMem(std::ostream &os) {}
static void showLeaks(std::ostream &os) {}
static void showVitals(std::ostream &os) {}
static bool leaksExist() { return false; }
};

#endif //USE_MEMTRACKER

#endif //__MEMTRACKER_H__





Share this post


Link to post
Share on other sites
These lines:

MemTracker::BlockList MemTracker::sMemBlocks;
size_t MemTracker::sCurMem;
size_t MemTracker::sMaxMem;

should be defined in a .cpp somewhere.

Share this post


Link to post
Share on other sites
excellent. I also had to move the << overload to the .cpp file and put a prototype of it in the .h. Thanks guys.
-Greg

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!