1

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)其他一些更通用的解决方案?

4

1 回答 1

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;
}

但是,您仍然会在内部使用 operator new 冒 std::unordered_map 的风险。

于 2012-10-21T19:58:24.060 回答