C++遍历删除元素

C++遍历删除元素

转自:http://zencoder.info/2019/10/11/erase-element-from-container/

今天看到一个patch fix从std::map中遍历删除元素导致crash问题,突然意识到自己对如何正确地从map等C++容器中删除元素也没有很牢固清醒的认知。重新梳理了下这块的正确做法,记录在此,以备后忘。

基础知识

C++的容器按存储方式分为两类:

  • 以数组形式存储的顺序容器,如:vector,deque
  • 以不连续节点形式存储的容易,如:list, set, map

在使用erase方法遍历删除元素时,需要注意一些问题,否则就会踩坑。

对容器进行增删元素操作,可能会使迭代器失效。如果一个元素已经被删除,则其对应的迭代器会失效,不应该再被使用;否则会导致程序无定义的行为,基本上就会挂了。

正确的遍历删除方法

对于遍历删除map、list、set可以使用下面2种正确方法:

1. 使用删除元素之前的迭代器定义下一个元素,建议使用的方式

for (auto it=mymap.begin(); it!=mymap.end();) {
    if (it->first == target) {
        mymap.erase(it++); //here is the key
    } else {
        it++;
    }
}

2. 使用erase()返回下一个元素的迭代器

for (auto it=mymap.begin(); it!=mymap.end();) {
    if (it->first == target) {
        it = mymap.erase(it);
    } else {
        it++;
    }
}

注意:在对 vector、deque遍历删除元素时,可以通过erase的返回值来获取下一个元素的位置,也就是上面的第2种方法;但不能使用上面的第1种方法来遍历删除。

错误的遍历删除方法

把经常会踩坑的错误的写法贴在下面,作为警示!

下面的写法是错误的!下面的写法是错误的!下面的写法是错误的!

for (auto it=mymap.begin(); it!=mymap.end(); it++) {
    if (it->first == target) {
        mymap.erase(it); //这里的写法是错误的,错误的,错误的!!!
        //it对应的元素已经被删除,it迭代器失效,在for循环中执行it++会导致未定义行为
    }
}

下面的写法对vector是错误的!下面的写法对vector是错误的!下面的写法对vector是错误的!

for (auto it=myvector.begin(); it!=myvector.end();) {
    if (*it == target) {
        myvector.erase(it++); //对vector不能工作
    } else {
        it++;
    }
}
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值