给定是一个具有以下元素的类:
std::array<Class*, 4> children;
在调试模式下,检查nullptr
上未初始化数组的元素会返回true
。
if(children[0]==nullptr)
在发布模式下(启用了优化,无论是O1,O3还是Os),检查都会返回false
。
似乎元素以某种方式初始化,但访问它们仍然会导致分段错误。为避免此行为,我必须使用std::array
元素显式初始化nullptr
。
std::array<Class*, 4> children{{nullptr}};
为什么会这样?
编辑:在这种情况下使用的编译器是Apple LLVM 4.2 (Xcode 4.6.3)
。
答案 0 :(得分:3)
std::array
是聚合,与内置数组一样,因此如果它们不是用户定义的类型,则无法保证自动初始化其元素(元素与用户定义的类型是默认构造的)。您不能依赖具有任何特定价值的元素。在您的情况下,可能是在调试(非优化)模式下,它从堆栈中分配新的空间,恰好已经被清零,但是在启用优化的情况下,编译器可能会意识到它可以重用不再需要的空间,但保留旧数据。
答案 1 :(得分:2)
在调试模式下,行为取决于编译器。一些编译器/调试器设置魔术值(例如VS使用0xCDCDCDCD)一些使用零(完全不好)。在释放模式下,内存未初始化。这就是它可能在某些编译器的调试模式下工作的原因,但从未发布过。
答案 2 :(得分:1)
因为未初始化(不是静态存储持续时间)变量的内容是“不确定的” - 不可能知道它将是什么,并且可能随时间而变化,这取决于任何数量的因素。
编译器将为不同的优化级别生成不同的代码,这可能会导致内存中变量的不同布局。如果要查看可预测的行为,则必须初始化变量。还有其他任何因素,它将取决于任何数量的因素,包括优化级别,你得到的“结果”。
答案 3 :(得分:0)
Visual可以在未初始化的内存上设置幻数。 无论如何,你无法明显地测试未初始化的内存