1

Given 是一个具有以下元素的类:

std::array<Class*, 4> children;

nullptr在调试模式下,检查返回的未初始化数组的元素true

if(children[0]==nullptr)

但是,在发布模式下(启用优化,无论是 O1、O3 还是 Os),检查返回false

似乎元素以某种方式初始化,但访问它们仍然会导致分段错误。为了避免这种行为,我必须显式地初始化std::arraywithnullptr元素。

std::array<Class*, 4> children{{nullptr}};

为什么会这样?

编辑:在这种情况下使用的编译器是Apple LLVM 4.2 (Xcode 4.6.3).

4

4 回答 4

3

std::array是一个聚合,就像内置数组一样,因此如果它们不是用户定义的类型(具有用户定义类型的元素是默认构造的),则不能保证自动初始化其元素。您不能依赖具有任何特定价值的元素。在您的情况下,可能是在调试(非优化)模式下,它从恰好已经清零的堆栈中分配新空间,但是启用优化后,编译器可能会意识到它可以重用不再需要的空间,但保留旧数据。

于 2013-09-02T17:21:04.397 回答
2

在调试模式下,行为取决于编译器。一些编译器/调试器设置魔法值(例如 VS 使用 0xCDCDCDCD)一些使用零(一点也不好)。在释放模式下,内存未初始化。这就是它可以在某些编译器的调试模式下工作的原因,但永远不会在发布中工作。

于 2013-09-02T17:19:43.840 回答
1

因为未初始化(不是静态存储持续时间)变量的内容是“不确定的” - 无法知道它将是什么,并且可能会因多种因素而异。

编译器会针对不同的优化级别生成不同的代码,这可能会导致变量在内存中的布局不同。如果您想看到可预测的行为,那么您必须初始化变量。其他任何事情,这将取决于任何数量的因素,包括优化级别,你得到什么“结果”。

于 2013-09-02T17:20:35.647 回答
0

视觉可能会在未初始化的内存上设置幻数。无论如何,你不能明显地测试未初始化的内存

于 2013-09-02T17:17:56.107 回答