Multiple Definitions

Started by
5 comments, last by Greg K 19 years, 2 months ago
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
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?
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
#ifndef __MEMTRACKER_H__#define __MEMTRACKER_H__#include <cstdlib>#include <string>#include <list>#include <bitset>#include <iostream>#include <iomanip>#ifdef USE_MEMTRACKERenum 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_MEMTRACKERclass 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__
And sure enough, I am getting errors on the variables it is trying to instantiate.
-Greg
These lines:
MemTracker::BlockList MemTracker::sMemBlocks;size_t MemTracker::sCurMem;size_t MemTracker::sMaxMem;

should be defined in a .cpp somewhere.
excellent. I also had to move the << overload to the .cpp file and put a prototype of it in the .h. Thanks guys.
-Greg

This topic is closed to new replies.

Advertisement