STL中vector与list迭代器erase操作触发段错误的问题排查
问题与代码分析
给定一个数组,需将元素复制到vector和list中,要求通过erase的单迭代器形式删除vector内的偶数元素、list内的奇数元素。运行提供的代码时出现段错误,但注释掉for循环中list相关逻辑后,程序可正常运行(仅list未完成奇数元素删除)。
原代码
#include <iostream> #include <vector> #include <list> #include <algorithm> using namespace std; int main(){ int ia[] = {0,1,1,2,3,5,8,13,21,55,89}; int len = sizeof(ia) / sizeof(ia[0]); // 初始化vector和list vector<int> vec; list<int> lst; for(int i=0; i!=len; i++){ vec.push_back(ia[i]); lst.push_back(ia[i]); } // 打印初始内容 cout<<"Vector: "<<endl; for(auto ele: vec) cout<<ele<<" "; cout<<"\nList: "<<endl; for(auto ele: lst) cout<<ele<<" "; // 目标:vector仅保留奇数,list仅保留偶数 vector<int>::iterator iv = vec.begin(); list<int>::iterator il = lst.begin(); for(; iv!=vec.end(), il!=lst.end(); iv++, il++){ if((*iv % 2) == 0){ int temp = *iv; vector<int>::iterator iter = find(vec.begin(), vec.end(), temp); if(iter != vec.end()) vec.erase(iter); } else if((*il % 2) == 1){ int temp = *il; list<int>::iterator iter = find(lst.begin(), lst.end(), temp); if(iter != lst.end()) lst.erase(iter); } } // 打印处理后内容 cout<<"\n\nNew Vector containing odd numbers: "<<endl; for(auto ele: vec) cout<<ele<<" "; cout<<"\nNew List containing even numbers: "<<endl; for(auto ele: lst) cout<<ele<<" "; }
注释list逻辑后的输出
Vector: 0 1 1 2 3 5 8 13 21 55 89 List: 0 1 1 2 3 5 8 13 21 55 89 New Vector containing odd numbers: 1 1 3 5 13 21 55 89 New List containing even numbers: 0 1 1 2 3 5 8 13 21 55 89
问题根源
- 循环条件错误:使用逗号表达式
iv!=vec.end(), il!=lst.end(),实际仅会判断后者是否成立。当vector元素被删除后长度变短,iv会超出vector的有效范围,触发未定义行为(段错误)。 - 删除逻辑冗余且错误:用
find查找元素再删除完全没必要,且会删错位置(比如重复元素时,find返回第一个匹配项而非当前迭代器指向的元素),同时大幅降低效率。 - 迭代器失效处理错误:vector执行
erase后,当前及后续迭代器都会失效,直接执行iv++会访问无效内存;list的erase仅使被删除的迭代器失效,但同步遍历vector和list的逻辑本身不成立——两者删除元素后长度变化不同步,无法用同一个循环同步处理。 - 分支逻辑漏洞:
else if导致只有当vector当前元素是奇数时,才会处理list的元素,遗漏了大量需要删除的list奇数元素。
修正后的代码
#include <iostream> #include <vector> #include <list> using namespace std; int main(){ int ia[] = {0,1,1,2,3,5,8,13,21,55,89}; int len = sizeof(ia) / sizeof(ia[0]); vector<int> vec; list<int> lst; for(int i=0; i!=len; i++){ vec.push_back(ia[i]); lst.push_back(ia[i]); } // 打印初始内容 cout<<"Vector: "<<endl; for(auto ele: vec) cout<<ele<<" "; cout<<"\nList: "<<endl; for(auto ele: lst) cout<<ele<<" "; // 删除vector中的偶数元素 auto iv = vec.begin(); while(iv != vec.end()){ if(*iv % 2 == 0){ iv = vec.erase(iv); // erase返回下一个有效迭代器 } else { ++iv; } } // 删除list中的奇数元素 auto il = lst.begin(); while(il != lst.end()){ if(*il % 2 == 1){ il = lst.erase(il); // list的erase同样返回下一个有效迭代器 } else { ++il; } } // 打印处理后内容 cout<<"\n\nNew Vector containing odd numbers: "<<endl; for(auto ele: vec) cout<<ele<<" "; cout<<"\nNew List containing even numbers: "<<endl; for(auto ele: lst) cout<<ele<<" "; return 0; }
修正后输出
Vector: 0 1 1 2 3 5 8 13 21 55 89 List: 0 1 1 2 3 5 8 13 21 55 89 New Vector containing odd numbers: 1 1 3 5 13 21 55 89 New List containing even numbers: 0 2 8
内容的提问来源于stack exchange,提问作者Swayam Badhe
相关产品推荐
相关产品推荐

