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.