C++迭代器控制流问题:vector扩容时传入的end迭代器是否更新
// 原示例存在多处语法错误:函数名定义和调用不匹配、调用语句缺少分号、模板参数T未声明等 void myFunk(std::vector<T>& v, std::vector<T>::iterator first, std::vector<T>::iterator last) { while (first != last) { if ((*first) > (*last)) { // 错误:last是尾后迭代器,不可解引用 T someT; v.push_back(someT); } first++; } } int main(){ std::vector<T> foo = {some, T, values}; myFunky(foo, foo.begin(), foo.end()) // 错误:函数名不匹配、缺少分号 return 0; }
这段代码首先存在多处未定义行为,既不会保证无限循环,也不会保证执行foo.size()次迭代后结束,完全没有确定的行为。
关于你关心的迭代器问题,有两个明确的结论:
- 迭代器是值传递,函数参数
last是调用时foo.end()的拷贝,不存在任何自动同步更新的机制,无论vector后续怎么扩容、增减元素,last的值都会保留函数调用时传入的初始值,不会自动更新为新的尾后迭代器。 std::vector调用push_back时如果触发容量扩容(即当前元素数量等于vector的预留容量),会重新分配整块连续内存,此时所有原有的迭代器、指针、引用都会立即失效,对失效迭代器执行比较、自增、解引用等操作都属于未定义行为,程序可能崩溃、输出异常结果,也可能出现无限循环,没有任何规范约束其行为。
额外补充:end()返回的尾后迭代器不指向任何有效元素,你代码中直接对last执行解引用操作*last本身就属于未定义行为,和扩容无关,只要执行到这行代码,程序行为就已经不可控。
内容的提问来源于stack exchange,提问作者Pedro Barbeira
相关产品推荐
相关产品推荐

