Sign in to follow this  

Multiple Definitions

This topic is 4717 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
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
And sure enough, I am getting errors on the variables it is trying to instantiate.
-Greg

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

This topic is 4717 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this