2

匿名の名前空間内にグローバル変数があります。

namespace {
std::unordered_map<std::string, std::string> m;
}


A::A() { m.insert(make_pair("1", "2")); } // crasches
void A::insert() { m.insert(make_pair("1", "2")); } // ok

mapコンストラクターの内部を使用しようとすると、アクセス違反の読み取り場所が表示されます。Aしかし、初期化した後で使用すると機能します。
この動作は正しいですか?

4

2 に答える 2

8

Aコンストラクター呼び出しがクラッシュの原因となっているオブジェクトのスコープは?

静的イニシャライザが実行される順序に関する保証はないため、Aオブジェクトがグローバルまたは静的でもある場合 (そのまま)、有効に構築されたオブジェクトであるという点でまだ存在しないm可能性が非常に高くなります。つまり、mへのstd::unordered_map::insert()呼び出しが初期化されていないメモリで呼び出されるため、クラッシュが発生します。

A解決策は、依存するすべてのインスタンスがm、静的/グローバルではなく、明示的に作成されていることを確認することです (または、同じ TU にある場合は、適切に順序付けするためにコメント作成者が追加したように)、または構造を変更します。挿入をA行うために後でインスタンスで関数を呼び出すことができるようにします。これが有効な解決策であるかどうかは、 の包括的な使用法によりAます。

于 2012-08-13T13:29:57.767 に答える
2

Aアプリケーションのどこかで、つまりmain()関数が実行される前に、つまり初期化される前に、静的コンテキストでタイプのクラスを作成している可能性がありmます。

于 2012-08-13T13:31:39.777 に答える