问题描述
#include <iostream>
using namespace std;
int main() {
int x = 10;
while (x>0) {
x = x-1;
cout << x << "\n";
}
return 0;
}
在这个简单的程序中,我改变了一个while循环的迭代器的值。但是这样做安全吗?程序有时会遇到段错误吗?
这个伪代码怎么样:
vector <vector<Struct> > all_vectors;
vector<Struct> old_vector,new_vector;
Initialize old_vector;
all_vectors.push_back(old_vector);
index = 0;
while (all_vectors[index].size()>0) {
calculate new_vector;
if (new_vector not empty) all_vectors.push_back(new_vector);
index += 1;
}
我的真实代码有点混乱和冗长,所以我只发布了我真实代码的主要思想。但是对于这种情况,我遇到了分段错误。当我尝试调试时,问题似乎出在以下行上:index += 1。 我不明白为什么。如果我的代码不可读,我很抱歉,我只是在学习 C++。
解决方法
你想问一下改变循环变量(x)的值是否安全。请记住,迭代器是指向容器内元素的对象(如指针),因此整数变量 int x
不是迭代器。
现在,您的问题的答案是,在循环体内更改循环变量的值是完全安全的。如果不更改循环变量的值,就不能期望循环终止!
进入第二部分,不合逻辑地更改值会导致无限循环或分段错误。假设您在循环体中写入了 x=x+1
而不是 x=x-1
,在这种情况下 x 的值将始终大于 0,因此循环将永远不会终止。
我现在猜测,但是如果您的循环看起来像您提供的第二个示例,则可能是由于 while 语句中的检查导致的分段错误。
...
index = 0;
while (all_vectors[index].size() > 0) {
^-- This,this could be the problem
...
index += 1;
}
原因是程序试图访问超出范围的向量。 这可能会解决问题
...
while (index < all_vectors.size() && all_vectors[index].size() > 0) {
^---- Check this index first ^---- only checked if first condition is true
...
从外观上看,我建议改用 for 循环:
...
for (size_t index = 0; index < all_vectors.size() && all_vectors[index].size() > 0; ++i) {
...
我还建议在向量出现分段错误时使用 .at() 而不是 operator[]
,因为这样可以进行范围检查,并且可以帮助您更快地找到问题。
为了推进(在典型情况下),改变输入迭代器的值本质上是必要的。如果您不更改用作结束条件的迭代器,那么您将永远不会到达迭代的末尾,除非迭代从末尾开始 - 即迭代次数为零。
请注意,迭代器与循环变量的概念不同,但答案同样适用于循环变量。