对象周围的堆栈已损坏
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);
中的语句有什么问题吗我尝试用{}在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]
越界。
您需要考虑有两个不同的构造在这里工作。
初始化
// 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个元素,而不是声明一个名为elem
的大小为5的新数组
当您改用(0, 0, 0, 0, 0)
时,错误就会消失,因为这是一个计算结果为0
的表达式,并且您可以将0
分配给int
数组的元素。
不幸的是,您这样做是针对一个不存在的元素,因为elem[5]
超出了界限。它是一个五元素数组中的第六个元素。
不能使用initializer语法一下子分配给数组的所有元素是C和C++的限制。
要在任意位置分配给数组,您必须在循环中逐个分配,或者使用填充函数:
std::fill(std::begin(elem), std::end(elem), 0);
…这无论如何都要好得多。
幸运的是,你犯了另一个非常方便的罪行:你实际上确实想要初始化,尽管目前你是在构造函数内部赋值。要初始化类成员,您必须使用构造函数的成员初始化器列表,而且,碰巧的是,构造函数的成员-初始化器列表使我们能够使用初始化器语法:
arr2()
: elem{0, 0, 0, 0, 0}
{}
…或者,更简单地说:
arr2()
: elem{}
{}
分配
elem[5]=(0,0,0,0,0);
在数组中的第六个位置写一个零(阅读逗号运算符((请记住,数组索引是基于零的(,它是数组末尾之外的一个。写入超出数组的边界会导致未定义的行为。
有几种方法可以初始化数组,最简单的是构造函数初始化器列表:
class arr2
{
int elem[5];
public:
arr2()
: elem{}
{}
};
以上将值初始化数组,这意味着数组中的每个元素也将被值初始化,对于int
值初始化,将其设置为0
。
为了扩展您得到的错误,现在几乎所有的系统和编译器都在堆栈上存储本地变量,其中包括main
函数中的变量obj
。将对象放置在堆栈上也会将其成员变量放置在堆栈中。如果您在数组的边界外写入,那么您也会在没有权限的堆栈内存上写入,从而损坏堆栈。
这并不能达到您的预期:
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;
因为你正在破坏这段记忆。你有例外。
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 变量周围的堆栈'...'已损坏
- 运行时检查失败 #2 变量"A"周围的堆栈已损坏
- 运行时检查失败 #2 - 变量"e"周围的堆栈已损坏。发生
- 变量周围的堆栈'sortArray'已损坏
- 变量周围的堆栈'folderPath'已损坏
- 运行时检查失败 #2 - 变量周围的堆栈'...'已损坏
- 运行时检查失败 #2 - 变量"l1"周围的堆栈已损坏
- C++:此代码可以编译,但引发运行时检查失败 #2 - 围绕变量周围的堆栈'num'已损坏。发生
- 数组变量周围的堆栈已损坏
- 运行时检查失败 - 变量周围的堆栈已损坏
- 调试:运行时检查失败 #2 - 变量"LoggerThread"周围的堆栈已损坏
- 运行时检查失败 #2 - 变量周围的堆栈'k'已损坏
- 运行时检查失败 #2 - 变量"数字选择"周围的堆栈已损坏
- 数组问题:变量周围的堆栈'arr'已损坏
- 运行时间检查:变量周围的堆栈已损坏
- 变量周围的堆栈'Yarray'已损坏
- 变量"name"周围的堆栈已损坏C++
- 运行时检查失败#2 - 变量周围的堆栈'myArray'已损坏.- 似乎无法弄清楚如何删除此错误
- MS 工作室 17 变量周围的堆栈已损坏