|
|
1
74
初始化的求解顺序:首先,这只是一个暂时的解决办法,因为您有一些全局变量,您正试图消除它们,但还没有时间(您最终将消除它们,不是吗?:-)
C++11 做
正式保证静态函数对象的构造是线程安全的。所以从技术上来说
请注意: 不要 使用 double checked locking pattern 尝试并避免锁定的成本。这在C++03中不起作用。 创建问题:在创建时,没有任何问题,因为我们保证它是在可以使用之前创建的。
|
|
|
2
31
我只是写了一些代码来追踪这个问题。我们有一个很好的代码库(1000多个文件),在Windows/VC++2005上运行良好,但在Solaris/gcc上启动时崩溃。 我编写了以下.h文件:
和内部 .cpp文件在解决方案中,我添加了以下内容:
运行应用程序时,您将获得如下输出文件:
如果您遇到崩溃,罪魁祸首应该在最后列出的.cpp文件中。至少,这将为您提供一个设置断点的好位置,因为这段代码应该是 绝对优先 要执行的代码的一部分(在此之后,您可以逐步浏览代码并查看所有正在初始化的全局变量)。 笔记:
|
|
3
15
根据编译器的不同,可以在构造函数初始化代码处放置断点。在VisualC++中,这是
然后进入每个函数以获取文件和函数名(假设您已使用上的调试信息进行编译)。获得名称后,退出函数(返回到
全部的 静态初始值设定项,而不仅仅是代码中的初始值设定项——这是获得详尽列表的最简单方法。您可以过滤掉无法控制的内容(例如第三方库中的内容)。 该理论适用于其他编译器,但函数的名称和调试器的功能可能会改变。 |
|
4
5
也许可以使用valgrind查找未初始化内存的使用情况。“静态初始化顺序失败”的最佳解决方案是使用静态函数,该函数返回如下对象的实例:
这种访问静态对象的方法是通过调用getStatic,这将保证它在第一次使用时初始化。 如果您需要考虑取消初始化的顺序,请返回一个新的对象,而不是静态分配的对象。
|
|
|
5
5
有一种代码,基本上是“初始化”编译器生成的C++。找到这段代码/调用堆栈的一个简单方法是创建一个静态对象,其中包含一些在构造函数中取消引用NULL的内容-在调试器中中断并稍微研究一下。MSVC编译器设置一个函数指针表,该表为静态初始化而迭代。您应该能够访问此表并确定程序中发生的所有静态初始化。 |
|
|
6
4
这不是一个小问题,但如果您的代码具有易于解析的中间格式表示,至少可以按照相当简单的步骤来完成。 1) 找到所有具有非平凡构造函数的全局变量,并将它们放入列表中。 2) 对于每个非平凡构造的对象,生成由其构造函数调用的整个潜在函数树。 3) 遍历非平凡构造函数树,如果代码引用任何其他非平凡构造的全局函数(在步骤1中生成的列表中非常方便),则可能存在早期静态初始化顺序问题。 4) 重复步骤2&3直到用尽步骤1中生成的列表。 注意:如果您有一个类的多个全局,则可以通过每个对象类只访问一次潜在函数树而不是每个全局实例访问一次来优化此功能。 |
|
|
7
1
用全局函数替换所有全局对象,这些全局函数返回对函数中声明为静态的对象的引用。这不是线程安全的,所以如果你的应用程序是多线程的,你可能需要一些技巧,比如pthread_once或全局锁。这将确保在使用之前初始化所有内容。 现在,要么你的程序工作(万岁!)或者它位于一个无限循环中,因为您有一个循环依赖项(需要重新设计),或者您转到下一个bug。 |
|
|
8
1
您需要做的第一件事是列出所有具有非平凡构造函数的静态对象。 有鉴于此,您要么需要一次插入一个,要么简单地用单例模式对象替换它们。 singleton模式受到了很多批评,但是懒惰的“按需”构造是解决现在和将来大多数问题的一种相当简单的方法。 古老的
新的。。。
当然,如果您的应用程序是多线程的,这可能会给您带来比最初更多的问题。。。 |
|
9
1
Gimpel软件(www.Gimpel.com)声称,他们的PC Lint/FlexeLint静态分析工具将检测此类问题。
|
|
|
10
1
其中一些答案现在已经过时了。为了像我这样来自搜索引擎的人: 在Linux和其他地方,通过谷歌的 AddressSanitizer .
然后,您将执行以下操作:
https://github.com/google/sanitizers/wiki/AddressSanitizerInitializationOrderFiasco |
|
|
11
0
其他答案是正确的,我只是想补充一点,对象的getter应该在.cpp文件中实现,而不应该是静态的。如果您在头文件中实现它,那么对象将在您从中调用它的每个库/框架中创建。。。。 |
|
|
12
0
如果您的项目在Visual Studio中(我已经用VC++Express 2005和Visual Studio 2008 Pro尝试过这一点):
这应该会给你一个很好的列表,列出所有受影响的全局变量 . 最后,更好的方法是尝试从项目中删除这些对象(有时说起来容易做起来难)。 |
|
|
Tom Buck · c#程序在整数列表上冻结 8 年前 |
|
|
Ran Lavi · 在c中初始化结构的指针++ 8 年前 |
|
|
Js_zero · 在c++中实例化对象有几种方法,它们之间有什么区别 8 年前 |
|
|
jfernal · 节点。js在加载其他函数之前等待初始化变量 8 年前 |
|
|
Victor · 在javafx中运行时更改标签文本 8 年前 |
|
|
blubb · 在Kotlin中是否有更惯用的方法来初始化此映射? 8 年前 |
|
|
Bing Bang · 初始化包含字节数组的结构数组 8 年前 |