我想我知道如何在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