我有以下一段代码,在运行抛出错误之后:
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;
}
ERROR 围绕变量&#39; obj&#39;已经腐败了。
如果我删除arr2 obj;
,那么它可以正常工作。
类本身或ctor elem[5]=(0,0,0,0,0);
中的语句是否有任何错误
我尝试在main中用{}定义一个数组,它工作正常。在课堂上我不知道为什么会失败。
int arr4[4]={1,2,3,4}; //OK
答案 0 :(得分:3)
int elem[5]; // Represents that the array is of size 5
由于数组索引以0开头,因此可用的数组索引为:
elem[0]
elem[1]
elem[2]
elem[3]
elem[4]
(共五个要素)
elem[5]
超出范围。
答案 1 :(得分:2)
作业
elem[5]=(0,0,0,0,0);
在数组的第六个处写一个零(读the comma operator)(记住数组索引是从零开始的),这是超出数组末尾的一个。超出数组范围的写入会导致undefined behavior。
有几种方法可以初始化数组,最简单的是构造函数初始化列表:
class arr2
{
int elem[5];
public:
arr2()
: elem{}
{}
};
以上将value-initialize数组,这意味着数组中的每个元素也将进行值初始化,而int
值初始化将其设置为0
。
为了扩展您所获得的错误,几乎所有系统和编译器都会在堆栈中存储局部变量,其中包括obj
函数中的变量main
。将对象放在堆栈上也会将其成员变量放在堆栈上。如果你写出数组的边界,那么你也写在堆栈内存上,你没有权利,因此破坏了堆栈。
答案 2 :(得分:2)
你需要考虑这里有两种截然不同的结构。
// 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 th 元素,而不是声明一个名为5的新数组elem
。当您使用(0, 0, 0, 0, 0)
时错误消失,因为这是an expression that evaluates to 0
,您可以将0
分配给int
数组的元素。
不幸的是,你正在对一个不存在的元素这样做,因为elem[5]
超出范围。这是五元素数组中假设的第六个元素。
无法使用初始化语法一次性分配给所有数组的元素是C和C ++的限制。
要在任意位置分配数组,您必须在循环中逐个分配它们,或者使用填充函数:
std::fill(std::begin(elem), std::end(elem), 0);
......无论如何都要好得多。
幸运的是,你犯了另一个非常方便的犯罪:你实际上做想要初始化,即使你现在正在构造函数体内进行分配。 To initialise class members, you must use the constructor's member-initialiser list并且,实际上,构造函数的成员初始化列表使我们能够使用初始化语法:
arr2()
: elem{0, 0, 0, 0, 0}
{}
......或者更简单:
arr2()
: elem{}
{}
答案 3 :(得分:0)
这不符合您的期望:
elem[5]=(0,0,0,0,0);
您在索引5
(超出范围)中分配值为0.您不分配初始化列表,而是分配一系列零,其间有逗号运算符(返回第二个)每次调用的价值),然后返回最右边的零。
答案 4 :(得分:0)
elem[5]=(0,0,0,0,0); //{} throws error i dont know why
使用{}抛出错误,因为{}必须仅用于数组的初始化,而不是用于赋值。
上面的语句也没有将所有数组元素分配给零,而是尝试将一个零分配给elem [5],这实际上超出了数组的边界。 你的数组从elem [0]开始,到elem [4]结束。
elem [5]实际上是指下面定义的向量的地址。 矢量vec;
因为你正在腐蚀这段记忆。你有例外。