1)我的项目中有一些静态类,它们在构造函数中分配变量。
class StaticClass
{
public:
char *var;
StaticClass()
{
var=new char[100];
}
};
static StaticClass staticClass;
2)我重写了new和delete运算符,并让它们跟踪std :: unordered_map中的所有当前分配
unordered_map<void*,size_t> allocations;
void* operator new[](size_t size)
{
void *p=malloc(size);
if (p==0) // did malloc succeed?
throw std::bad_alloc(); // ANSI/ISO compliant behavior
allocations[p]=size;
return p;
}
当我的程序启动时,staticClass的构造函数在分配构造函数之前被调用,因此operator new()尝试在初始化之前将大小插入到分配中,这些错误。
以前,当我遇到静态构造的问题时,我只是将std :: map变成了一个NULL指针,然后在第一次使用它时初始化它,确保它在我第一次有效时插入它:
unsorted_map<void*,size_t> *allocations=NULL;
//in code called by static constructor:
if(allocations==NULL)
allocations=new unsortedmap()
//now safe to insert into allocations
但是,这将不再有效,因为我将在operator new()中调用new,从而创建一个无限的递归循环。
我知道我可以通过制作另一个特殊版本的operator new来解决这个问题,它需要一些令牌参数来区分它,并且只是用它来初始化分配,但是在更一般的(学习)意义上,我更愿意以某种方式
a)强制分配在StaticClass执行之前初始化(最好)
b)有一些方法可以调用默认运算符new而不是我重写的运算符(我认为不可能,但是......)
c)其他一些更通用的解决方案?答案 0 :(得分:0)
避免初始化顺序问题的一种简单方法是将静态对象包装在函数中:
unordered_map<void*,size_t> &allocations()
{
static unordered_map<void*,size_t> static_map;
return static_map;
}
然后像这样使用它:
void* operator new[](size_t size)
{
void *p=malloc(size);
if (p==0) // did malloc succeed?
throw std::bad_alloc(); // ANSI/ISO compliant behavior
allocations()[p]=size;
return p;
}
但是,您仍然在内部使用new new运行std :: unordered_map的风险。