Sign in to follow this  
Greg K

Multiple Definitions

Recommended Posts

Greg K    122
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
Evil Steve    2017
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
Greg K    122

#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

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