【发布时间】:2023-03-10 18:41:01
【问题描述】:
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() 尝试在分配被初始化之前将 size 插入到分配中,这会出错。
以前,当我遇到静态构造顺序问题时,我只是将 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) 其他更通用的解决方案?
【问题讨论】:
-
如果地图最终使用您的 operator new 在内部分配空间,这似乎有无限递归的潜力。似乎您需要为您的地图使用自定义分配器。
-
“这个”是什么意思?我指出了为地图制作自定义分配器的解决方案,但如果存在,我更愿意实际学习更通用的解决方案
-
"this" 表示定义一个自定义运算符 new,地图可能会在内部使用它。
-
通过“自定义分配器”我不是指不同的运算符 new。我指的是 unordered_map
的第五个模板参数。