首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

2013-03-28 
stl 容器的问题 在其他地方移除元素后 另一个地方迭代崩溃#include stdio.h#include tchar.h#include

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++也没有什么作用啊。

热点排行