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

循环遍历 std:map 并删除元素解决方案

2012-02-04 
循环遍历 std::map 并删除元素C/C++ codeint main(int argc, char* argv[]){mapstring, string mapData

循环遍历 std::map 并删除元素

C/C++ code
int main(int argc, char* argv[]){    map<string, string> mapData;        mapData["a"] = "aaa";     mapData["b"] = "bbb";     mapData["c"] = "ccc";     for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); i++)    {        if (i->first == "b")        {            mapData.erase(i);        }    }    return 0;}


崩溃了,据说是i指针在元素被删除后失效了,回到for语句中与mapData.end()进行比较时访问违例,这个没有问题。


C/C++ code
int main(int argc, char* argv[]){    map<string, string> mapData;        mapData["a"] = "aaa";     mapData["b"] = "bbb";     mapData["c"] = "ccc";     for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); /*i++*/)    {        if (i->first == "b")        {            mapData.erase(i++);        }        else        {            i++;        }    }    return 0;}


这是网上找的删除方法,不会崩溃。
请问为什么写成下面这样就又不行了?

C/C++ code
int main(int argc, char* argv[]){    map<string, string> mapData;        mapData["a"] = "aaa";     mapData["b"] = "bbb";     mapData["c"] = "ccc";     for (map<string, string>::iterator i=mapData.begin(); i!=mapData.end(); /*i++*/)    {        if (i->first == "b")        {            mapData.erase(i/*++*/);        }        else        {            /*i++*/;        }         i++;    }    return 0;}



[解决办法]
STL的删除操作,可能导致迭代器失效,注意这一点就好了。

http://hi.baidu.com/fdwm_lx/blog/item/f670e7353233d11d91ef3969.html

看看这篇文章吧
[解决办法]
呵呵,有时候也别随便提取公因式。。。

[解决办法]
探讨

第二段代码和第三段代码,有区别吗?我觉得应该一样啊
if (i->first == "b")
{
mapData.erase(i/*++*/);
}

[解决办法]
LZ 仔细想想
map 内部不是顺序存储 实际数据结构是红黑树
你可以认为是琏式存储结构
iter相当于指向你要删除的这个节点
仔细想想 链表的删除 删除完 你还能通过指向原来这个删除接点的指针来找后继吗?

所以要 erase(iter++)
说白了就是
iterator temp = iter++;
erase(temp);


[解决办法]
i++操作主要做三件事情:
1、首先把i备份一下。
2、把i加上1。
2、返回第一步备份的i。

因此,
C/C++ code
mapData.erase(i++);
[解决办法]
注意 这是后置++唯一不能拆开写的情况。

C/C++ code
mapData.erase(i);   //i erase以后   i已经失效,不能再用i++;i++; 

热点排行