グローバル メモリは C++ で初期化されますか?
-
09-06-2019 - |
質問
グローバル メモリは C++ で初期化されますか?もしそうなら、どのようにして?
(2 番目) の説明:
プログラムが起動するとき、プリミティブが初期化される前に、グローバル メモリとなるメモリ空間には何があるか?たとえば、それがゼロになっているのか、それともゴミなのかを理解しようとしています。
状況は次のとおりです。シングルトン参照を設定できますか? instance()
初期化の前に次のように呼び出します。
MySingleton* MySingleton::_instance = NULL;
その結果、2 つのシングルトン インスタンスが得られるでしょうか?
シングルトンの複数のインスタンスに関する私の C++ クイズを参照してください...
解決
はい、グローバル プリミティブは NULL に初期化されます。
例:
int x;
int main(int argc, char**argv)
{
assert(x == 0);
int y;
//assert(y == 0); <-- wrong can't assume this.
}
クラス、構造体、配列、ヒープ上のメモリ ブロックについては、いかなる仮定も行うことはできません。
常にすべてを初期化するのが最も安全です。
他のヒント
標準から:
静的ストレージ期間 (3.7.1) を持つオブジェクトは、他の初期化が行われる前にゼロ初期化 (8.5) されます。ゼロ初期化と定数式による初期化を総称して呼びます。 静的初期化;他のすべての初期化は 動的初期化. 。定数式 (5.19) で初期化された静的ストレージ期間を持つ POD [plain old data] タイプ (3.9) のオブジェクトは、動的初期化が行われる前に初期化されます。同じ翻訳単位内の名前空間スコープで定義され、動的に初期化される静的記憶期間を持つオブジェクトは、その定義が翻訳単位に現れる順序で初期化されます。[注:8.5.1 では、集合メンバーが初期化される順序について説明しています。ローカル静的オブジェクトの初期化は6.7で説明されています。
したがって、静的ストレージ期間を持つグローバルは初期化されます。たとえばヒープ上に割り当てられたグローバルは、当然ながら自動的には初期化されません。
埋め込まれた世界から来ています...
コードは 3 種類のメモリにコンパイルされます。
1.。データ:初期化されたメモリ
2.。文章:定数とコード
3..bss:未初期化メモリ (明示的に初期化されていない場合、C++ では 0 に初期化されます)
グローバルは初期化されると .data に入ります。そうでない場合、それらは .bss に配置され、プリメイン コードでゼロ化されます。
静的/グローバル スコープで宣言された変数は、少なくとも VC++ では常に初期化されます。
状況によっては、実際に次の動作に違いが生じる可能性があります。
int x = 0;
int main() { ... }
そして
int x;
int main() { ... }
共有データ セグメントを使用している場合、VC++ は少なくとも明示的な初期化の存在と、 #pragma data_seg
特定の変数をプロセスの共有データ セグメントに入れるかプライベート データ セグメントに入れるかを決定します。
さらに面白くするには、共有データ セグメントで宣言されたコンストラクター/デストラクターを持つ静的 C++ オブジェクトがある場合に何が起こるかを考えてみましょう。コンストラクター/デストラクターは、exe/dll がデータ セグメントにアタッチされるたびに呼び出されますが、これはほぼ確実に必要なものではありません。
詳細はこちら KB 記事