C ++ / MSVC中固定大小的对象初始化顺序

时间:2015-10-22 14:44:02

标签: c++ c++11 stl visual-studio-2015

我的项目中有一个类定义,类似于:

class A { std::map<type> some_map; };

class B { A array_of_a[10]; std::map<type> some_map; };

class C { B array_of_b[15]; std::map<type> some_map; };

class D { C array_of_c[5]; std::map<type> some_map; };

class E { D d; };

它在MSVC中编译时没有任何错误或警告,但当我尝试运行我的程序时,我尝试在我的堆栈上创建类 E 的对象,有时 (比如50%的运行)我从std :: map或其他STL类型(例如我在类 E 中使用的互斥体)中得到奇怪的“访问冲突写入”异常上面的类构造函数调用。

我没有在我的程序中创建任何显式线程,这段代码只是从常规 main()运行,但是这个bug的非确定性让我感觉像MSVC做了一些对我来说是幕后优化,并决定为我做一些奇怪的非序列化初始化。

我的代码实际发生了什么以及我做错了什么?初始化包含STL类字段的静态大小的对象数组是错误的吗?

1 个答案:

答案 0 :(得分:2)

问题在于无法保证初始化程序的运行顺序。这被称为“静态初始化顺序惨败”:https://isocpp.org/wiki/faq/ctors#static-init-order

在该链接上有一些很好的信息,但简短的版本是你需要构建你的代码,以便在你第一次使用它时初始化或构建对象。这样,您就可以保证按照您在代码中使用它们的顺序初始化它们的顺序。