迭代器结束检查在“for”循环内递增后失败
Iterator end check fails after incrementing inside a `for` loop
这个问题很可能是重复的,但我没有找到关于这个问题的任何内容。
为什么递增放置在vector
中最后一个位置的iterator
会使它不等于vector.end()
?
或者,换句话说,为什么这正常执行:
int main() {
vector<string> vec = {"ve"};
for (auto it = vec.begin(); it != vec.end(); it++) {}
return 0;
}
虽然这个进入了一个无限循环:
int main() {
vector<string> vec = {"ve"};
for (auto it = vec.begin(); it != vec.end(); it++) { it++; }
return 0;
}
而这个:
int main() {
vector<string> vec = {"ve"};
for (auto it = vec.begin(); it != vec.end(); it++) {
cout << (it == vec.end()) << " ";
cout << (*it == "ve") << endl;
it++;
}
return 0;
}
导致打印SEGFAULT
:
0 1
0
因此,it
实际上被递增了,因此其内容变为空(根据调试器进行了优化(,但它并没有等于vec.end()
。为什么?
想象一下it
在vec.end()
之前指向一个,据说是for
循环的最后一次迭代。
-
it != vec.end();
将被true
,因此循环将继续。 - 执行体内的
it++;
。it == vec.end()
现在。 - 执行来自
for
环路头的it++
。it
点一个超越vec.end()
.
vec.end()
指向vec
的最后一个元素之外的一个元素,它仍然是明确定义的。 vec.end() + 1
(it
的最终值(指向vec
的最后一个元素之外的两个元素,这是未定义的行为。
这意味着取消引用迭代器会访问未分配的内存(解释分段错误(。再次未定义的行为。
您正在检查it != vec.end()
但是由于it++
发生了两次,您在每次检查时跳过两次。换句话说,你跑过了vector
的尽头而没有发现它。
如果你在向量中添加一个元素,那么循环将到达终点并停止,因为你将不再跳过终点(显然这不是一个"正确的"修复,它只是演示了问题(。
要修复它,请在循环中的增量之前检查结束。您也可以检查在条件中使用operator<
,但这有点风险,因为您将无效it
保留一段时间,这对将来的代码维护不利。
在 for 循环中,迭代器上的增量操作是循环中的最后一个(也是隐式(操作。
情况 1:循环以 "it" = vec.begin(( 开头。什么也没发生。"它"递增(隐式(。它 = vc.end((。循环结束。因此是正常行为。
情况 2:循环以它开头 = vec.begin((。"它"递增。它 = vc.end((。"它"再次递增(隐式(。"它"移动到下一个内存位置,并在每个周期中不断增加。因此,无限循环。
情况 3:循环以它开头 = vec.begin((。检查是否 == vc.end((。返回假。打印"it"引用的内存位置中的值。"它"递增。它 = vc.end((。"它"再次递增(隐式(。"it"移动到下一个未分配的内存位置。因此,SEG故障。
- C/C++:socket() 创建在循环中失败,打开的文件太多
- 谁能弄清楚为什么我的循环会失败?
- 断言失败:列出迭代器不可递增(不在循环中)
- 对于循环执行失败,因为变量我不会递增,为什么?
- GCC自动矢量化在减少循环中失败
- 密码检查程序-匹配密码失败-循环失败
- c++ 中带有容器迭代器的循环类型依赖关系(GCC 失败,而 MSVC 正常)
- 线程未正确结束:它忽略失败的循环条件
- 在循环中第二次调用luaT_pushudata时失败
- 在for循环内部使用setw是失败的
- 用于循环计数器失败的 C++
- 输入验证循环在第一次输入失败后无法正常工作
- std::vector push_back 在并行 for 循环中使用时失败
- 循环迭代后共享指针断言失败
- 对于循环不递增或循环不失败测试
- fgetwc EOF 循环测试失败,但 65535 正常
- 在字符串上循环以查看字符串失败的位置
- 当循环失败时,当读取int和字符串C++时
- 迭代器结束检查在“for”循环内递增后失败
- 编译不完整类型失败;循环依赖