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 のコンストラクターが呼び出されるため、演算子 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

ただし、演​​算子 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;
}

ただし、演​​算子 new を内部的に使用すると、 std::unordered_map のリスクが引き続き発生します。

于 2012-10-21T19:58:24.060 に答える