映射和列表的迭代器显示不同的行为

时间:2016-06-14 20:57:27

标签: c++ list dictionary iterator segmentation-fault

我遇到了关于堆栈溢出的this帖子,并找到了迭代删除列表中元素的方法。我想对maplist尝试相同的操作。我按预期得到了list的分段错误,但我没有得到map的分段错误。为什么会这样?

以下是两者的代码。

使用列表:

#include <iostream>
#include <list>
using namespace std;
int main()
{
   list<int>l ;
   l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);
   list<int>::iterator it;
   for(it = l.begin();it!=l.end();it++){
       l.erase(it);
       cout<<"Give me some output..\n";
   }
   return 0;
}

Output :

Give me some output..
Segmentation fault (core dumped)

使用地图:

#include <iostream>
#include <map>
using namespace std;
int main()
{
   map<int, int>m ;
   m[1] = 1;m[2] = 2;m[3] = 3;m[4] = 4;
   map<int,int>::iterator it;
   for(it = m.begin();it!=m.end();it++){
       m.erase(it);
       cout<<"Give me some output..\n";
   }
   return 0;
}

Output :

Give me some output..
Give me some output..
Give me some output..
Give me some output..

不应该列出迭代器和映射迭代器显示相同的行为??

ASIDE:

我遇到的实际问题是我在大程序中使用地图并尝试使用上面提到的错误方法从中删除元素,我得到了分段错误。然后我访问了上面提到的链接并解决了问题。但是这两个代码都不应该给出分段错误。使用相同代码片段的两个代码如何显示不同的行为。是一个代码是小的,因此编译器能够自己纠正它吗?

1 个答案:

答案 0 :(得分:2)

list::erasemap::erase状态:

  

擦除元素的引用和迭代器无效。其他引用和迭代器不受影响。

当您随后致电it++时,您正在递增无效引用Undefined Behavior

幸运的是,这是一个简单的问题需要解决,因为两个容器'erase - 方法都会返回下一个有效的迭代器,所以如果由于某种原因你不想只调用clear,你可以这样做:

for(auto it = cbegin(l); it != cend(l); it = l.erase(it)) cout << "Give me some output..\n";