【问题标题】:how are map iterators invalidated when erasing elements? [duplicate]擦除元素时如何使映射迭代器失效? [复制]
【发布时间】:2011-11-13 01:48:13
【问题描述】:

使用擦除方法时,迭代器何时以及如何在映射中失效?

例如:

std :: map < int , int > aMap ;

aMap [ 33 ] = 1 ;
aMap [ 42 ] = 10000 ;
aMap [ 69 ] = 100 ;
aMap [ 666 ] = -1 ;

std :: map < int , int > :: iterator itEnd = aMap.lower_bound ( 50 ) ;

for ( std :: map < int , int > :: iterator it = aMap.begin ( ) ;
      it != itEnd ;
      // no-op
    )
{
   aMap.erase ( it ++ ) ;
}

被擦除的迭代器肯定会变得无效(它会在仍然有效时递增) 但是其他人呢?

如果我没记错的话,标准说映射必须是平衡的二叉树或具有等效键搜索复杂度的结构

如果地图是用树实现的,我可以假设未擦除的迭代器仍然有效吗?

还有其他可能的方法来实现地图吗?

【问题讨论】:

    标签: c++ stl iterator std stdmap


    【解决方案1】:

    如果地图要实现为平衡树,在执行擦除后,树可能需要重新平衡,这意味着迭代器指向的位置现在可能有其他内容或没有,具体取决于重新平衡树,这就是为什么当您从地图中删除元素时迭代器无效的原因,在删除元素后,迭代器现在最终指向一些 不再有效的内存,即未定义的行为

    如果你决定从地图中删除所有元素,在你的循环中,迭代器将指向什么结束?

    【讨论】:

    • map::erase 只会使作为其参数传递的迭代器无效。所有其他迭代器都保证保持有效。
    • 通过修改指向节点的内部指针来重新平衡树;值本身不会移动,对它们的引用和迭代器仍然有效。
    • @Mankarse:我稍微修改了我的答案,以符合你所说的
    • OK(cmets 已删除)-但您仍然说迭代器无效,因为树可能会重新平衡。事实并非如此 - 它已失效,因为它指的是不再存在的东西。
    【解决方案2】:

    只有被擦除的迭代器是无效的,其余的由标准保证保持有效。

    Iterator invalidation rules

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-11
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      相关资源
      最近更新 更多