直接删除vector元素需防迭代器失效,正确做法有三:一是用erase返回值更新迭代器;二是反向遍历避免影响未处理元素;三是批量删除时采用remove-erase惯用法提升效率。

在C++中,直接在循环中删除vector元素可能导致迭代器失效,从而引发未定义行为。关键是要正确处理erase()操作对迭代器的影响,并选择合适的遍历方式。
使用erase()返回有效迭代器
调用vector::erase()会删除元素并返回指向下一个有效元素的迭代器。利用这一特性可以安全删除:
- 不要先erase再++,而是用erase的返回值更新迭代器
- 避免在erase后继续使用已失效的迭代器
示例代码:
for (auto it = vec.begin(); it != vec.end();) { if (should_remove(*it)) { it = vec.erase(it); // erase返回下一个位置 } else { ++it; } }
反向遍历删除(推荐)
从后往前遍历能避免删除时影响前面还未访问的元素:
- 使用reverse_iterator或下标从size()-1开始递减
- 删除不会影响已处理的部分
- 逻辑清晰,不易出错
示例代码:
for (int i = vec.size() - 1; i >= 0; --i) { if (should_remove(vec[i])) { vec.erase(vec.begin() + i); } }
使用remove-erase惯用法(最高效)
对于批量删除满足条件的元素,标准做法是结合std::remove和erase:
立即学习“C++免费学习笔记(深入)”;
- std::remove将所有要保留的元素前移
- 返回新的逻辑结尾,再用erase一次性清理尾部
- 性能优于多次调用erase
示例代码:
vec.erase( std::remove_if(vec.begin(), vec.end(), [](const T& item) { return should_remove(item); }), vec.end() );
基本上就这些。根据场景选择方法:单次删除用erase返回值,多元素删除优先考虑remove-erase,简单逻辑可用逆序遍历。关键是不让迭代器失效。


