调用vector.erase(iterator)删除奇数时出现segmentation error的问题
问题根本原因
- 遍历
std::vector的同时直接删除元素会导致迭代器失效:你使用的范围for循环(for(auto j:ivec))底层基于迭代器实现,调用erase方法删除元素后,当前位置及之后的所有迭代器、包括循环提前缓存的末尾迭代器都会直接失效,后续遍历会访问非法内存,触发段错误。 - 你用
find匹配值找迭代器的逻辑本身存在缺陷:如果容器内有重复值(比如示例中的两个1),find每次只会返回第一个匹配值的迭代器,删除逻辑本身就是错误的。 - 至于修改判断条件删除偶数时没有报错,仅为偶发现象:测试用例中偶数数量少,删除操作刚好没有触发访问越界的极端场景,不代表代码符合规范,只是没有暴露问题而已。
正确实现方案
推荐使用STL标准的erase-remove惯用法实现批量删除,性能最高且不会出现迭代器失效问题:
#include <vector> #include <algorithm> int main() { std::vector<int> ivec = {0,1,1,2,3,5,8,13,21,34,55,89}; // remove_if将需要保留的元素移动到容器前半段,返回待删除区间的起始迭代器,erase批量删除对应区间 ivec.erase(std::remove_if(ivec.begin(), ivec.end(), [](int val){ return val % 2 != 0; }), ivec.end()); return 0; }
如果需要用循环遍历删除的写法,要正确接收erase的返回值(erase会返回删除元素之后的下一个有效迭代器):
#include <vector> int main() { std::vector<int> ivec = {0,1,1,2,3,5,8,13,21,34,55,89}; for(auto it = ivec.begin(); it != ivec.end(); ) { if (*it % 2 != 0) { it = ivec.erase(it); // 接收返回的有效迭代器,不需要手动自增 } else { ++it; // 不需要删除时才自增迭代器 } } return 0; }
内容的提问来源于stack exchange,提问作者meysamimani
相关产品推荐
相关产品推荐

