[英]stack around object was corrupted
我有以下代碼,運行后會拋出錯誤:
class arr2{
int count;
public:
int elem[5];
arr2()
{
count=-1;
elem[5]=(0,0,0,0,0); //{} throws error i dont know why
}
};
int main()
{
arr2 obj;
vector<int> vec;
vec.assign(10,42);
vector<int> ::iterator itr=vec.begin();
for(;itr!=vec.end();++itr){
cout<<*itr<<endl;
}
return 0;
}
變量'obj'周圍的錯誤堆棧已損壞。
如果我刪除arr2 obj;
然后就可以了 類本身或ctor elem[5]=(0,0,0,0,0);
的語句有什么問題嗎elem[5]=(0,0,0,0,0);
我試圖用{}在main中定義一個數組,它工作正常。 我不知道為什么在課堂上失敗。
int arr4[4]={1,2,3,4}; //OK
int elem[5]; // Represents that the array is of size 5
由於數組索引以0開頭,因此可用的數組索引為:
elem[0]
elem[1]
elem[2]
elem[3]
elem[4]
(共五個要素)
elem[5]
超出范圍。
分配
elem[5]=(0,0,0,0,0);
在數組的第六個位置寫入一個零(請閱讀有關逗號運算符的信息 )(請記住,數組索引是從零開始的),它是數組末尾的一個零。 超出數組范圍進行寫入會導致未定義的行為 。
有幾種初始化數組的方法,最簡單的方法是構造函數初始化列表:
class arr2
{
int elem[5];
public:
arr2()
: elem{}
{}
};
上面的代碼將對數組進行值初始化 ,這意味着數組中的每個元素也將被值初始化,對於int
值初始化,會將其設置為0
。
為了擴展您遇到的錯誤,當今幾乎所有系統和編譯器都將局部變量存儲在堆棧中,該局部變量在main
函數中包含變量obj
。 將對象放置在堆棧上還將其成員變量放置在堆棧上。 如果您寫出數組的邊界,那么您也將寫在您不擁有使用權的堆棧內存中,從而損壞堆棧。
您需要考慮這里有兩種不同的構造。
// initialiser
// |
// name ("elem") |
// | |
// ▼▼▼▼ ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
int elem[5] = {0, 0, 0, 0, 0};
// ▲▲▲ ▲▲▲
// \ /
// \ /
// \ /
// type (int[5])
// new element value
// |
// name ("elem") |
// | |
// ▼▼▼▼ ▼▼▼▼▼
elem[n] = 12345;
// ▲▲▲ ▲
// | |
// | assignment operator
// |
// index (n)
您的問題與以main
還是以類定義編寫代碼無關。 問題是您正在嘗試編寫分配 ,就好像它是初始化一樣 。
{0, 0, 0, 0, 0}
根本不能在分配中使用 elem[5]
而不是int elem[5]
,您是在命名elem
第 6 個元素,而不是聲明一個新的大小為5的數組elem
。 當您改用(0, 0, 0, 0, 0)
0,0,0,0,0)時,錯誤消失了,因為這是一個計算結果為0
的表達式,您可以將0
分配給int
數組的元素。
不幸的是,您對一個不存在的元素執行此操作,因為elem[5]
超出范圍。 它是五元素數組中假設的第六個元素。
一次無法使用初始化程序語法分配給數組的所有元素是C和C ++的局限性。
要在任意位置分配給數組,您必須在循環中一個接一個地分配它們,或使用fill函數:
std::fill(std::begin(elem), std::end(elem), 0);
…反正好多了。
幸運的是,您犯下了另一種實際上很方便的罪行:您實際上確實想初始化,即使此刻您正在構造器主體內進行賦值。 要初始化類成員,必須使用構造函數的member-initialiser列表 ,並且在發生這種情況時,構造函數的member-initialiser列表使我們能夠使用初始化語法:
arr2()
: elem{0, 0, 0, 0, 0}
{}
…或更簡單地說:
arr2()
: elem{}
{}
這不能達到您的期望:
elem[5]=(0,0,0,0,0);
您將索引5
處的元素(超出范圍)的值指定為0。您沒有分配初始化程序列表,而是分配了一系列零,並且中間使用逗號(返回每個調用的第二個值),其中依次返回最右邊的零。
elem[5]=(0,0,0,0,0); //{} throws error i dont know why
使用{}會引發錯誤,因為{}僅用於數組的初始化,而不能用於賦值。
同樣,上面的語句沒有將所有數組元素都分配為零,而是嘗試為elem [5]分配一個零,這實際上超出了數組的邊界。 您的數組以elem [0]開始,以elem [4]結尾。
elem [5]實際上是指下面定義的向量的地址。 向量vec;
當您破壞此內存時。 你有例外。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.