提问人:ranstar74 提问时间:3/24/2023 更新时间:3/28/2023 访问量:87
C++ 对局部静态变量的依赖
C++ Dependency on local static variable
问:
当调用重载的新运算符时,我的内存分配器被初始化:
MyAllocator* GetAllocator()
{
static MyAllocator allocator;
return &allocator;
}
void* operator new(size_t size)
{
return GetAllocator()->Allocate(size);
}
构造分配器时,它会创建记录器。 在销毁时,它会打印出所有内存泄漏。
MyAllocator::MyAllocator()
{
m_Logger = Logger::Create("Allocator.log");
m_Logger->Writef("...");
}
MyAllocator::~MyAllocator()
{
m_Logger->Writef("%u Leak(s) Total", m_LeakCount);
}
因为 Logger::Writef 使用本地静态缓冲区,所以我需要静态互斥锁。
Logger::Writef(const char* fmt, ...)
{
static char buffer[4096];
static Mutex mutex;
mutex.Lock();
...
}
这样,我们得到以下初始化顺序:
- GetAllocator::分配器
- 记录器::Writef::mutex
破坏的顺序是相反的,这给了我们:
- 记录器::Writef::mutex
- GetAllocator::分配器
交易是这样的,当 Logger::Writef 从 MyAllocator 的析构函数调用时,Logger::Writef::mutex 已经被破坏了。
答:
0赞
Mark Ransom
3/28/2023
#1
你的问题很简单。它是由破坏的顺序引起的,所以你所要做的就是改变破坏的顺序。
正如你所指出的,破坏的顺序与建造的顺序相反。因此,您需要确保在分配器之前构造记录器变量。
为此,可以将静态记录器变量移出函数范围,并将它们放在模块范围中。它们将在程序启动时构建。通过将它们放在匿名命名空间中,它们不会暴露给其他模块。
namespace
{
static char buffer[4096];
static Mutex mutex;
}
Logger::Writef(const char* fmt, ...)
{
mutex.Lock();
...
}
评论
Logger::Writef::mutex
是一个函数局部静态,它将在程序的生命周期内存在。Writef
MyAllocator