编译器生成的默认构造函数会初始化std :: array中指向nullptr的指针吗?

时间:2019-04-27 18:31:58

标签: c++ arrays initialization std

在给出以下代码的情况下,编译器应该生成Node()并应调用std::array<Node *, 100>()来初始化所有指向nullptr的100个指针。

旁注:我知道如果我使用std::array<Node *, 100> children {};可以做到这一点,但是我并不是想让我的代码正常工作(已经这样做了),而是想确保它不起作用。偶然地。

struct Node
{
    int value;
    std::array<Node *, 100> children;
}

更新:

这里的指针是垃圾:

struct Node
{
    int value;
    std::array<Node *, 100> children;
}

struct Node
{
    Node() : children() {}
    int value;
    std::array<Node *, 100> children;
}

这里的指针为nullptr:

struct Node
{
    int value;
    std::array<Node *, 100> children {};
}

struct Node
{
    Node() : children{} {}
    int value;
    std::array<Node *, 100> children;
}

请纠正我的错误。

3 个答案:

答案 0 :(得分:5)

std::array的构造函数中引用cppreference

  

按照聚合初始化规则初始化数组   (请注意,默认初始化可能会导致不确定的值   对于非T类)

通过声明像std::array<Node *, 100> children;这样的变量,可以调用默认的构造函数。并且,根据初始化规则,未默认初始化POD(intchardouble,指针等)。因此,不,如果不使用聚合初始化,则不会使用nullptr初始化数组。

聚合初始化

std::array<Node *, 100> children;

调用默认的构造函数,但未提供聚合初始化器,因此不会发生聚合初始化。但是

std::array<Node *, 100> children{}
std::array<Node *, 100> children = {};

不仅调用默认构造函数,还执行聚合初始化。在这种情况下,聚合{}仅是空的。并且,按照聚合初始化的规则,如果初始化程序少于数据成员,则每个未初始化的成员将被默认初始化。所以

Node x;
std::array<Node *, 100> children = {&x};

例如,将使用指向x的指针初始化第一个数组元素,而每个后续元素将默认初始化为nullptr

答案 1 :(得分:1)

根据this answerstd::array指针的默认初始化将初始化其包含的指针,并且它们的值将不确定。

std::array<Node *, 100> children; // pointers are uninitialized

但是,您可以使用 value 初始化来初始化所有包含的指向nullptr的指针。在std::array上,这具有值初始化数组中的每个值的效果,而后者又将每个指针归零。

std::array<Node *, 100> children {}; // pointers are all null

在成员初始化器列表中,您还可以按照以下步骤进行操作:

Node::Node() : children{/* value init array */} {/* empty c'tor body */}

答案 2 :(得分:0)

在为指针分配值之前,默认情况下,它指向“垃圾”地址。编译器不会为它们分配默认值nullptr。实际上,它不会为指针分配任何“默认”值。
编辑:
来自cppreference documentation for std::array

  

请注意,默认初始化可能会导致非类T的不确定值

因此,如果使用默认构造函数,则需要自己为每个元素分配nullptr的值。