暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

C++ STL之std::map::erase的用法及陷阱

分布式存储技术进阶 2019-12-17
5867

map的简介和使用

map是STL里重要容器之一。它的特性总结来讲就是:所有元素都会根据元素的键值key自动排序(也可根据自定义的仿函数进行自定义排序),其中的每个元素都是<key, value>的键值对,map中不允许有键值相同的元素,因此map中元素的键值key不能修改,但是可以通过key修改与其对应的value。如果一定要修改与value对应的键值key,可将已存在的key删除掉,然后重新插入。

map<string, int> m; // 定义一个空的map m,键是string类型的,值是int类型的

m["hello"] = 2; // 将key为"hello", value为2的键值对(key-value)存入map中


// 用迭代器器遍历,输出map中所有的元素,键用it->first获取,值用it->second获取

for (auto it = m.begin(); it != m.end(); it++) {

cout << it->first << " " << it->second << endl;

}

其他使用方法不再举例说明。


std::map::erase的用法及常见错误


STL的map表里有一个erase方法,用来从一个map中删除掉指定的节点。

先看基本的使用方法:

map<string,string> mapTest;

map<string,string>::iterator pit = mapTest.find(key);

if(pit != mapTest.end())

{

  mapTest.erase(iter);

}


像上面这样只是删除单个节点,map的erase操作不会导致问题,

但是当在一个循环里使用erase的时候,往往会导致错误。


常见的错误例子:

    map<int,string> mapTest;

    map<int, string>::iterator itor ;


    for (itor = mapTest.begin(); itor != mapTest.end(); ++itor)

    {

        if (itor->second == "abc")

        {

            mapTest.erase(itor) ; //错误的写法

        }

    }


原因分析:

map是关联式容器,调用erase后,当前迭代器已经失效,然后对itor进行操作,会发生传说中的“未定义的行为”!


在循环中正确使用map::erase的方法是什么呢?如下:

    map<int,string> mapTest;

    map<int, string>::iterator itor ;

    for (itor = mapTest.begin(); itor != mapTest.end();)

    {

        if (itor->second == "abc")

        {

            mapTest.erase(itor++) ; 

        }


    }


或者使用while循环

    map<int,string> mapTest;

    map<int, string>::iterator itor ;


    while (itor != mapTest.end();)

    {

        if (itor->second == "abc")

        {

            m.erase(itor++) ; 

        }


    }

该解决方法较详细的一种解释为:

http://blog.csdn.net/lmh12506/article/details/9167653

该方法中利用了后缀++的特点,这个时候执行mapInt.erase(it++);这条语句分为三个过程

1、先把it的值赋值给一个临时变量做为传递给erase的参数变量

2、因为参数处理优先于函数调用,所以接下来执行了it++操作,也就是it现在已经指向了下一个地址。

3、再调用erase函数,释放掉第一步中保存的要删除的it的值的临时变量所指的位置。


值得一提的是,在最新的C++11标准中,已经新增了一个map::erase函数执行后会返回下一个元素的iterator。也可以使用erase的返回值使得迭代器获得下一个有效的地址。


文章转载自分布式存储技术进阶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论