C++ 中迭代器失效问题

踩过的坑,记录一下,另外这个问题在c++ primer 9.3.6节有详细的说明

insert和eraser操作会使迭代器失效,虽然这个网上已经有很多总结了,但我还是写一下吧

insert操作在vector中会炸,而在list中不会,比如下面这个代码运行会直接炸

int main(void) {
    vector<int> s{ 1,2,3,4,5,6,7,8 };
    
    for (auto i = s.begin(); i != s.end(); ++i) {
        if (*i == 3)
            s.insert(i, 30);
        
    }
    for (auto i : s)
        cout << i << " ";
}

需要修改为以下代码

int main(void) {
    vector<int> s{ 1,2,3,4,5,6,7,8 };
    
    for (auto i = s.begin(); i != s.end(); ++i) {
        //cout << *i << " ";
        if (*i == 3) {
            i = s.insert(i, 30);
            ++i;
        }
        
    }
    for (auto i : s)
        cout << i << " ";
}

有两个地方一个是i = s.insert(i, 30),insert操作会返回插入位置的迭代器。

还有一个是下一行的++i,因为insert是插入参数i的前一个位置,如果不进行递增,会形成死循环。

另一种eraser的情况也是类似

int main(void) {
    vector<int> s{ 1,2,3,4,5,6,7,8 };
    
    for (auto i = s.begin(); i != s.end(); ++i) {
        //cout << *i << " ";
        if (*i == 3) {
            s.erase(i);
        }
        
    }
    for (auto i : s)
        cout << i << " ";
}

依旧是直接炸,需要改为

int main(void) {
    vector<int> s{ 1,2,3,4,5,6,7,8 };
    
    for (auto i = s.begin(); i != s.end();) {
        //cout << *i << " ";
        if (*i == 3) {
            i = s.erase(i);
        }
        else
            ++i;
        
    }
    for (auto i : s)
        cout << i << " ";
}

一个同之前一样需要获取删除后的迭代器。另一个是将++i操作拿出来,因为不拿出来的话被擦除的数据的后一位会被直接跳过。

最后引用下别人的总结

迭代器失效分三种情况考虑,也是分三种数据结构考虑,分别为数组型,链表型,树型数据结构。

数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);

链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。

注意:经过erase(iter)之后的迭代器完全失效,该迭代器iter不能参与任何运算,包括iter++,*ite

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值