C++ Dependency on local static variable

89 Views Asked by At

My memory allocator is initialized when overloaded new operator is called:

MyAllocator* GetAllocator()
{
    static MyAllocator allocator;
    return &allocator;
}

void* operator new(size_t size)
{
    return GetAllocator()->Allocate(size);
}

When allocator is constructed, it creates logger. On destructing, it prints out all memory leaks.

MyAllocator::MyAllocator()
{
    m_Logger = Logger::Create("Allocator.log");
    m_Logger->Writef("...");
}

MyAllocator::~MyAllocator()
{
    m_Logger->Writef("%u Leak(s) Total", m_LeakCount);
}

Because Logger::Writef uses local static buffer, I need static mutex.

Logger::Writef(const char* fmt, ...)
{
     static char buffer[4096];
     static Mutex mutex;

     mutex.Lock();
     ...
}

With this, we get following initialization order:

  • GetAllocator::allocator
  • Logger::Writef::mutex

Order of destruction is opposite, which gives us:

  • Logger::Writef::mutex
  • GetAllocator::allocator

And here's the deal, at point when Logger::Writef is called from destructor of MyAllocator, Logger::Writef::mutex is already destructed.

1

There are 1 best solutions below

0
Mark Ransom On

Your problem is simple. It's caused by the order of destruction, so all you have to do is change the order of destruction.

As you noted the order of destruction is opposite to the order of construction. So you need to make sure your logger variables are constructed before your allocator.

You can do this by moving your static logger variables out of function scope and putting them at module scope. They will be constructed at program startup. By putting them inside an anonymous namespace they won't be exposed to other modules.

namespace
{
     static char buffer[4096];
     static Mutex mutex;
}

Logger::Writef(const char* fmt, ...)
{
     mutex.Lock();
     ...
}