C++ STL容器 迭代器失效的问题

前言

对容器进行插入删除操作时,迭代器失效是什么意思

  • 对迭代器解引用,该地址上存放的值不再是操作前的值。(容易引起误解的一点是,有人把迭代器失效理解为无法访问)

容器分类

STL容器按照数据结构可以大致分为以下几类:

  • 数组型,比如vector、deque
  • 链表型,比如list
  • 树型,比如map,set,multimap,multiset

下面简单讲讲插入、删除对以上三种容器的影响

数组型容器

  • 插入时,若size < capacity,则插入点及之后的迭代器全部失效(插入后,所有旧迭代器仍然能访问,若以值是否在操作前后发生变化为考量,则仅有原先的end迭代器必定失效)。
  • 插入时,若size == capacity,则所有迭代器失效(插入后,所有元素分配到新的内存空间,不仅迭代器解引用的值发生变化,内存地址也发生了变化)。
  • 删除时,由于内存空间连续,会引起删除点之后的元素全部往前移动一个位置,因此删除点及之后的迭代器全部失效,可用以下代码正确迭代:
  • deque有些特殊,除了头尾两端,在任何地方插入和删除元素都将导致内存重新分配。
for (iter = cont.begin(); iter != cont.end();)
{
   (*it)->doSomething();
   if (shouldDelete(*iter))
      iter = cont.erase(iter); 
   else
      ++iter;
}

链表型容器

  • 插入时,不引起迭代器失效。
  • 删除时,只有当前迭代器失效。由于内存空间不连续,可用以下代码正确迭代(由于erase方式同样返回下一个有效的迭代器,也可以使用与数组型容器同样的方法正确迭代):
for (iter = cont.begin(); it != cont.end();)
{
   (*iter)->doSomething();
   if (shouldDelete(*iter))
      cont.erase(iter++);
   else
      ++iter;
}

树型容器

由于底层数据结构是红黑树,因此插入删除不影响其他节点,在插入时,红黑树会旋转重建,不引起迭代器失效。删除时,可用以下代码正确遍历:

for (iter = cont.begin(); it != cont.end();)
{
   (*iter)->doSomething();
   if (shouldDelete(*iter))
      cont.erase(iter++);
   else
      ++iter;
}

扩展

  • 为什么queue、stack没有迭代器?
    • 迭代器用于对数据结构中的元素进行顺序访问或随机访问。而队列queue只能从头部取,从尾部存,不能遍历(遍历可以理解为只读,而queue做不到只读,同样stack也不行)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值