STL中容器操作的迭代器失效-erase()函数陷阱

        迭代器失效都是发生在我们在使用容器的过程中要通过迭代器来删除某一个容器节点而导致的迭代器的失效,我们可以从各个容器使用的迭代器以及容器本身的构造结构找到答案,没必要,也不需要去记忆那些陷阱和正确的使用方法。

      每个容器的使用的迭代器类型具体可以到这篇博客去看,下面我们分别看一下每个容器的迭代器失效问题

1.vector 和deque

      这两种容器是支持随机访问迭代器的,可以随机说白了就是可以任意通过各种步长进行向前或者向后来访问容器节点,支持随机访问迭代器也是由于这两种容器本身节点的组成是地址顺序的,因此才可以根据随机的步长来访问各个节点。由于vector和deque在组成上都是顺序的,所以会出现当我们通过迭代器删除当前节点的时候,会导致再次访问后面的节点时候,当前迭代器指向的内存已经不可用了,所以会导致失效。原因在于,顺序结构会在删除本节点时候将后边的节点会依次向前进行移动。尤其是在容器内部实现会在扩容的时候将这段顺序节点转移到其他内存地址。

下面是正确的使用earse()函数进行节点删除的写法:(erase会返回删除节点后面节点的正确地址给迭代器变量)

std::vector< int> Vec;
std::vector< int>::iterator itVec;
for( itVec = Vec.begin(); itVec != Vec.end(); ){
      if( *itVec ){
          itVec = Vec.erase( itVec);
       }
      else{
          itList++;
       }
}
2.list  set 和map

     list 已经set和map这种关联式容器有一个共同的结构组成是他们都是通过不一定连续的节点结构组合起来的,各个节点之间通过保存彼此的地址实现关联,所以他们使用的迭代器类型是双向迭代器。这种迭代器会在删除当前节点时候,只会使当前节点地址失效,而不会使后边节点的地址失效。 因为他们无需进行每个节点中地址重新写入,我们依然可以根据当前删除节点迭代器找到下一个节点的地址。这里的erase()函数也会返回下一个节点的地址。

std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end();) {
      if( WillDelete( *itList) ){
            itList = List.erase( itList);
       }
       else{
            itList++;
      }
}
std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end();){
      if( WillDelete( *itList) ){
          List.erase( itList++);
      }
      else{
          itList++;
     }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值