读书人

stl 容器的有关问题 在其他地方移除元

发布时间: 2013-03-28 10:20:24 作者: rapoo

stl 容器的问题 在其他地方移除元素后 另一个地方迭代崩溃



#include <stdio.h>
#include <tchar.h>
#include <map>
using namespace std;

map<int,int> stl_Map;
void RemoveItera(int i)
{
map<int,int>::iterator stl_Iterator = stl_Map.find(i);
stl_Map.erase(stl_Iterator);
}

int main()
{
for (int i = 0;i < 20;i++)
{
stl_Map.insert(make_pair(i,i));
}

map<int,int>::iterator stl_Iterator = stl_Map.begin();
for (;stl_Iterator != stl_Map.end();stl_Iterator++) //移除后这里就挂了
{
if (stl_Iterator->second == 5)
{
RemoveItera(stl_Iterator->first);
}
}
return 0;
}



如何解决呢?

[解决办法]
在使用迭代器来遍历容器内容时,不能在遍历过程中使用erase移除迭代器,因为在使用erase后迭代器就失效了,再使用++iter时肯定会coredump了
[解决办法]
建议你先遍历容器,将需要移除的单元位置记录下来,然后再做移除操作。
[解决办法]
导致错误的原因如#1所说,但是也不是绝对不能在循环里调用erase。正确形式见下面代码:

map<int,int>::iterator stl_Iterator = stl_Map.begin();
for (;stl_Iterator != stl_Map.end();/*stl_Iterator++*/) //移除后这里就挂了
{
if (stl_Iterator->second == 5)
{
// map的erase函数本身就有删除某个迭代器位置的节点的重载形式
//RemoveItera(stl_Iterator->first);
stl_Map.erase(stl_Iterator++);// 这里只能采用后置形式,前置错
}
else
{
++stl_Iterator;// 这里前置后置都可以,但是前置效率高
}
}

[解决办法]

for (;stl_Iterator != stl_Map.end();) //移除后这里就挂了
{
if (stl_Iterator->second == 5)
{
stl_Map.erase(stl_Iterator++);
}
else
{
++stl_Iterator;
}
}

[解决办法]
stl_Map.erase(stl_Iterator);之后stl_Iterator就失效了。
stl_Iterator++会将stl_Iterator移向下一元素,但返回其原始值(指向原位置)的一个副本。
因此,当erase()被调用, pos已经不再指向那个即将被移除的元素了。
[解决办法]
删除一个元素后,迭代器就会自动指向被删除元素的下一个元素。参考下面的代码:

map<int,int>::iterator stl_Iterator = stl_Map.begin();
for (;stl_Iterator != stl_Map.end();/*stl_Iterator++*/) //移除后这里就挂了
{
if (stl_Iterator->second == 5)
{
stl_Iterator = stl_Map.erase(stl_Iterator++); // 这里只能采用后置形式,前置错
}
else
{
++stl_Iterator; // 这里前置后置都可以,但是前置效率高
}
}

------解决方案--------------------


erase前先把迭代器指向下一个结点。
[解决办法]

引用:
删除一个元素后,迭代器就会自动指向被删除元素的下一个元素。参考下面的代码:

请教 6 楼 pathuang68

stl_Iterator = stl_Map.erase(stl_Iterator++);
是否可以改为
stl_Iterator = stl_Map.erase(stl_Iterator);
呢,
个人觉得既然要做个赋值stl_Iterator++也没有什么作用啊。

读书人网 >C++

热点推荐