MacOS下C++ list调用erase()报Segmentation fault:11是什么原因?
错误原因
你触发段错误的核心原因是std::list的erase()方法调用后,传入的迭代器会直接失效,你后续继续使用这个失效的迭代器执行insert()操作属于非法内存访问,这是Segmentation fault 11、退出码139的直接诱因。std::list::erase()的标准行为是:移除迭代器指向的元素,返回值为被删除元素的下一个元素的有效迭代器,原传入的迭代器会变成野迭代器,不允许再进行读写、传参等任何操作。你现有代码中调用mylist.erase(it)后没有接收返回的有效迭代器,直接把已经失效的it作为位置参数传给insert(),就会触发内存访问错误。
解决方案
根据你的需求(删除值为2的元素后在对应位置插入9),有两种常用修复方案:
方案1:接收erase返回的有效迭代器执行插入
这是最贴合你原有先删后插逻辑的修改方式,代码修改如下:
#include <iostream> #include <list> using namespace std; int main () { list<int> mylist; list<int>::iterator it; for(int i=1;i<6;i++){ mylist.push_back(i); } for (it=mylist.begin(); it!=mylist.end(); ++it) cout << ' ' << *it; cout<<endl; for(it=mylist.begin(); it!=mylist.end();it++){ if((*it)==2){ // 接收erase返回的有效迭代器,指向被删元素的下一个元素 auto new_it = mylist.erase(it); // 在new_it位置前插入元素,刚好对应原2的位置 mylist.insert(new_it,9); break; } } for (it=mylist.begin(); it!=mylist.end(); ++it) cout << ' ' << *it; cout<<endl; return 0; }
修改后程序输出为:
1 2 3 4 5
1 9 3 4 5
方案2:直接修改迭代器指向的元素值
你的需求本质是替换指定位置的元素,不需要执行删除+插入操作,直接赋值即可,性能更高代码更简洁:
for(it=mylist.begin(); it!=mylist.end();it++){ if((*it)==2){ *it = 9; break; } }
运行效果和方案1完全一致。
内容的提问来源于stack exchange,提问作者Alim Tleuliyev
相关产品推荐
相关产品推荐

