zoukankan      html  css  js  c++  java
  • 迭代器失效

    原题

     1 CONTAINER::iterator iter , tempIt;
     2 for (iter = cont.begin() ; iter != cont.end() ; )      
     3 {
     4     tempIt = iter;
     5     ++iter;
     6     cont.erase(tempIt);
     7       
     8 }
     9  
    10 假设cont是一个CONTAINER的示例,里面包含数个元素,那么当CONTAINER为: 1、vector 2、list 3、map 4、deque 
    11 会导致上面的代码片段崩溃的CONTAINER类型是?
      答案:1,4
     
      1. vector,erase(pos),直接把pos+1到finish的数据拷贝到以pos为起点的区间上,也就是vector的长度会逐渐变短(所有元素前移),而后iter会逐渐往后移动,直到iter == cont.end(),由于容器中end()返回的迭代器是最后一个元素的下一个(这个地方没有任何值),现在考虑这个状态前一个状态,此时要删除的点是iter, tempIt = iter, ++iter会指向此时的end(),但是执行erase(tempIt)之后,end()向前移动了!此时iter空了!!!不崩溃才怪。
     
      2. list,erase(pos),干的事情很简单,删除自己,前后的节点连接起来就完了,所以iter自增的过程不会指空,不会崩溃喽。
     
      3. map,erase(pos),干的事情太复杂,但是我们需要知道的信息其实很少。该容器底层实现是RBTree,删除操作分了很多种情形来讨论的,目的是为了维持红黑树性质。但是我们需要知道的就是每个节点类似于list节点,都是单独分配的空间,所以删除一个节点并不会对其他迭代器产生影响,对应到题目中,不会崩溃喽。
     
      4. deque,erase(pos),与vector的erase(pos)有些类似,基于结构的不同导致中间有些步骤不太一致。先说说deque的结构(这个结构本身比较复杂,拣重要说吧,具体看STL源码),它是一个双向开口的连续线性空间,实质是分段连续的,由中控器map维持其整体连续的假象。其实题中只要知道它是双向开口的就够了(可以在头部或尾部增加、删除)。在题中有erase(pos),deque是这样处理的:如果pos之前的元素个数比较少,那么把start到pos-1的数据移到起始地址为start+1的区间内;否则把pos后面的数据移到起始地址为pos的区间内。在题中iter一直往后移动,总会出现后面数据比前面少的时候,这时候问题就和1一样了,必须崩溃!
     
      总结:关联容器(如map, set, multimap,multiset),删除当前的iterator,只会使当前的iterator失效,只要在erase时,递增当前iterator即可。对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置,位于该元素之前位置的迭代器不会失效。不过erase方法可以返回下一个有效的iterator,cont.erase(iter++)可以修改为cont.erase(iter)
    list使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator。
    只为训练自己,时刻锤炼一个程序员最基本的技能!
  • 相关阅读:
    IDEA下Maven的pom文件导入依赖出现Auto build completed with errors
    org.apache.jasper.JasperException: java.lang.NullPointerException
    Eclipse下导入web项目(Some projects cannot be imported because they already exist in the workspace)
    JS中构造函数的方法定义在原型对象里
    JS变量赋值
    JDBC以及连接池连接MySQL出现时区错误问题
    chrome中如何截取整个网页
    java中final、super、static关键字的使用
    初识less
    根据当前时间显示问候语
  • 原文地址:https://www.cnblogs.com/coding-wtf/p/5771177.html
Copyright © 2011-2022 走看看