迭代器是允许引用STL容器元素的对象,类似于指针。它们提供统一的访问方式,可以访问任何容器(如vector、list、map等)的元素。迭代器有几种类型:
特别需要关注迭代器的生命周期:
示例:
std::vector<int> v = {1,2,3,4,5}; for (auto it = v.begin(); it != v.end(); ++it) { if (*it == 3) { // 删除值为3的元素 it = v.erase(it); // erase返回下一个元素的迭代器 --it; // 需要时调整迭代器 } }
问题: 调用std::vector::insert时,迭代器是否会失效?
常见回答: 不,仅在添加超出末尾范围时。
正确答案: 所有与插入位置相等或位于其后的迭代器和引用会失效,如果容器的容量增加。如果容量足够,则仅失效插入位置之后范围的迭代器。
示例:
std::vector<int> v = {1,2,3}; auto it = v.begin() + 1; v.insert(v.begin(), 0); // it 在这里可能会失效!
事件:在项目中,使用指针迭代std::vector,并在push_back后继续通过失效的指针迭代,导致应用崩溃。
事件:开发者在for(auto it : list)中通过erase删除std::list中的元素,未使用返回的erase迭代器,导致某些元素被跳过并未全部删除。
事件:代码中使用了std::map,在按键调用erase后,迭代器仍然与已删除元素绑定(未定义行为)——这导致后续访问时发生随机崩溃。