直接删除 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,简单逻辑可用逆序遍历。关键是不让迭代器失效。


