我想我知道如何在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
的最后打印输出了那些奇怪的数字。如果我添加一个构造函数一个像这样:
struct A {
A(int i) : i{i} {}
int i;
};
然后最后打印出的输出变为:
'c: 3; 4; 5; 6'
理所应当。但现在delete[] c;
会给我一个运行时错误(不是一个例外),说MyGame.exe has triggered a breakpoint.
(我在VS2013工作)。
此外,如果我将行A* c = new A[] {
更改为A* c = new A[4] {
,则错误消失,并且所有内容都按预期工作。
所以我的问题是: 为什么奇怪的数字?如果我没有定义构造函数,数组中的A对象会不会得到正确的构造? 为什么我需要明确指定数组的大小,即使它会编译和链接就好了没有?以这种方式初始化堆栈上的数组不会给我一个运行时错误(我测试过它是肯定的)。
如果你要在堆上分配数组,你需要指定数组的大小。你分配的是一个指针(例如'A *')而不是一个数组。从它读取调用未定义的行为。 –
[这里](http://ideone.com/hZA0iM)它甚至不能编译! –
奇怪的数字是因为你的编译器有点坏。 g ++ 5.1表示“错误:预期的初级表达式'之前']'标记'和'错误:'A [1]'的初始化程序太多了。 VS 2015说“错误C3078:数组大小必须在新表达式中指定”。 VS2013对该代码做了什么不清楚。 – molbdnilo