c++ - 堆上的结构数组未正确初始化

标签 c++ arrays structure heap-memory

我以为我知道如何在 C++ 中处理内存管理,但这让我感到困惑:

考虑以下代码:

struct A {
    int i;
};

int main(int argc, char* argv[]) {
    A a{ 5 }; //Constructs an A object on the stack
    A* b = new A{ 7 }; //Constructs an A object on the heap and stores a pointer to it in b
    A* c = new A[] { //Construct an array of A objects on the heap and stores a pointer to it in c
        { 3 },
        { 4 },
        { 5 },
        { 6 }
    };
    std::cout << "a: " << a.i << "\n"; //Prints 'a: 5'
    std::cout << "b: " << b->i << "\n"; //Prints 'b: 7'
    std::cout << "c: " << c[0].i << "; " << c[1].i << "; " << c[2].i << "; " << c[3].i << "\n"; 
    //Prints 'c: -33686019; -1414812757; -1414812757; -1414812757'

    delete b;
    delete[] c;
    return 0;
}

我不明白为什么 c 的最后打印输出会打印出那些奇怪的数字。如果我像这样向 A 添加构造函数:

struct A {
    A(int i) : i{i} {}
    int i;
};

那么最后打印出来的输出就变成了:

'c: 3; 4; 5; 6'

本应如此。但是现在 delete[] c; 会给我一个运行时错误(看起来不是异常),说 MyGame.exe 触发了一个断点。(我正在工作VS2013)。

此外,如果我将行 A* c = new A[] { 更改为 A* c = new A[4] { 错误消失,一切正常正如预期的那样。

所以我的问题是: 为什么会有奇怪的数字?如果我不定义构造函数,数组中的 A 对象是否会以某种方式正确构造? 为什么我需要显式指定数组大小,即使没有它也可以编译和链接?以这种方式在堆栈上初始化数组不会给我运行时错误(我测试过它以确保)。

最佳答案

这是一个错误:

A* c = new A[] { {3}, {4}, {5}, {6} };

您必须将维度放在 [] 中。使用 new 时,无法从初始化列表中推导出数组维数。

4 放在这里使您的代码对我来说可以正常工作。

您的编译器显然具有将 new A[] 视为 new A[1] 的“扩展”。

如果你在标准模式下编译(使用 gcc 或 clang,-std=c++14 -pedantic),这总是一个好主意,编译器会告诉你这样的事情。将警告视为错误,除非您真的确定它们不是错误:)

关于c++ - 堆上的结构数组未正确初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33225139/

相关文章:

c++ - C++ 17 POSIX信号量或condition_variable?

ios - 多维数组展开可选值

.net - 用于 .NET 的无锁和线程安全 IList<T>

Python:通过字符串中的名称访问结构字段

链表中的 C++ 字符数组

c++ - C++ 生成器中的 "[ilink32] Fatal: Out of memory"

c++ - 使用 RTTI(或返回类型标签的虚函数)是否可行?

c++ - 遍历 C++ 映射的差异

具有自定义类的 BufferedReader 的 java.lang.StackOverflowError

javascript - 获取数组的最后两个位置