ここには「静的初期化順序の大失敗」に関するいくつかの良い質問と回答がありますが、クラッシュはしないがデータを失い、リークするため、特に醜い、さらに別の表現にぶつかったようです。
カスタム C++ ライブラリと、それに対してリンクするアプリケーションがあります。ライブラリには、クラスのすべてのインスタンスを登録する静的 STL コンテナーがあります。これらのインスタンスは、たまたまアプリケーションの静的変数です。
「大失敗」の結果 (私は信じています)、アプリケーションの初期化中にコンテナーがアプリケーション インスタンスでいっぱいになり、ライブラリが初期化され、コンテナーがリセットされ (おそらくメモリ リーク)、図書館。
これは、単純化されたコードで再現した方法です。
mylib.hpp:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class MyLibClass {
static vector<string> registry;
string myname;
public:
MyLibClass(string name);
};
mylib.cpp:
#include "mylib.hpp"
vector<string> MyLibClass::registry;
MyLibClass::MyLibClass(string name)
: myname(name)
{
registry.push_back(name);
for(unsigned i=0; i<registry.size(); i++)
cout << " ["<< i <<"]=" << registry[i];
cout << endl;
}
MyLibClass l1("mylib1");
MyLibClass l2("mylib2");
MyLibClass l3("mylib3");
myapp.cpp:
#include "mylib.hpp"
MyLibClass a1("app1");
MyLibClass a2("app2");
MyLibClass a3("app3");
int main() {
cout << "main():" << endl;
MyLibClass m("main");
}
オブジェクトを次のようにコンパイルします。
g++ -Wall -c myapp.cpp mylib.cpp
g++ myapp.o mylib.o -o myapp1
g++ mylib.o myapp.o -o myapp2
myapp1 を実行します。
$ ./myapp1
[0]=mylib1
[0]=mylib1 [1]=mylib2
[0]=mylib1 [1]=mylib2 [2]=mylib3
[0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1
[0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2
[0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2 [5]=app3
main():
[0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2 [5]=app3 [6]=main
myapp2 を実行します。
$ ./myapp2
[0]=app1
[0]=app1 [1]=app2
[0]=app1 [1]=app2 [2]=app3
[0]=mylib1
[0]=mylib1 [1]=mylib2
[0]=mylib1 [1]=mylib2 [2]=mylib3
main():
[0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=main
静的ベクトルが再初期化されたのか、それとも初期化前に使用されたのかという質問があります。これは予期される動作ですか?
ライブラリを 'mylib.a' (ar rcs mylib.a mylib.o) として 'ar' すると、問題は発生しませんが、.a にリンクするための有効な順序が 1 つしかなく、それが原因である可能性があります。ライブラリは最後に、myapp1 はここにあります。
しかし、私たちの実際のアプリケーションでは、多くのオブジェクト ファイルといくつかの静的 (.a) ライブラリがいくつかの静的レジストリを共有する、より複雑なアプリケーションで問題が発生しており、これまでに解決できた唯一の方法は、'[10.15 ] 「静的な初期化順序の大失敗」を防ぐにはどうすればよいですか?' .
(正しくリンクしているかどうかを確認するために、多少複雑なビルド システムを調査中です)。