Здесь есть несколько хороших вопросов и ответов по поводу «фиаско статического порядка инициализации», но я, кажется, наткнулся на еще одно его выражение, особенно уродливым, потому что он не дает сбоев, а приводит к потере и утечке данных.
У меня есть собственная библиотека C ++ и приложение, связанное с ней. В библиотеке есть статический контейнер STL, который регистрирует все экземпляры класса. Эти экземпляры оказываются статическими переменными в приложении.
В результате "фиаско" (я полагаю), мы получаем контейнер, заполненный экземплярами приложения во время инициализации приложения, затем инициализируется библиотека и контейнер становится сбросить (возможно, утечка памяти), в результате остались только экземпляры из библиотеки.
Вот как я воспроизвел его с помощью упрощенного кода:
mylib.hpp:
#include
#include
#include
using namespace std;
class MyLibClass {
static vector registry;
string myname;
public:
MyLibClass(string name);
};
mylib.cpp:
#include "mylib.hpp"
vector MyLibClass::registry;
MyLibClass::MyLibClass(string name)
: myname(name)
{
registry.push_back(name);
for(unsigned i=0; i
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
Возникает вопрос, статический вектор был повторно инициализирован или использовался перед инициализацией? Это ожидаемое поведение?
Если я ' ar 'библиотека как' mylib.a '(ar rcs mylib.a mylib.o), проблема не возникает, но, вероятно, потому, что существует только один допустимый порядок для ссылки на .a, и это наличие библиотеки в последнее место, что касается myapp1 здесь.
Но в нашем реальном приложении, более сложном, с множеством объектных файлов и несколькими статическими (.a) библиотеками, разделяющими несколько статических реестров, проблема возникает, и мы можем пока удалось решить эту проблему, применив '[10.15] Как мне предотвратить «фиаско статического порядка инициализации»? ».
(Я все еще изучаю нашу довольно сложную систему сборки, чтобы узнать, мы связываемся правильно).