STL中的迭代器失效

马谦马谦马谦 2020年1月15日20:07:36 发表评论
文章最后编辑于:2020-1-20 20:09:10

一、迭代器失效

向容器添加或者删除元素可能会导致指向容器的指针、引用或者迭代器失效。使用已经失效的指针、引用或者迭代器将会导致程序出现异常,编码过程中一定要时刻注意迭代器失效的场景。

例如,以vector为例:

执行以上代码会导致段错误:

STL中的迭代器失效

原因:在循环中新增了元素,并且重新分配了内存空间,导致迭代器失效。使用已经失效的迭代器会导致程序出现段错误。

迭代器失效,主要有两个层面的意思:

  1. 无法通过迭代器++或--操作遍历整个stl容器,记作第一层失效
  2. 无法通过迭代器存取迭代器所指向的内存,记作第二层失效

二、失效场景

vector和string

如果增加或删除元素导致内存空间重新分配了,那么指向容器的迭代器都会失效(第二层失效)。如果存储空间未重新分配,指向删除元素之前的所有迭代器还有效(第一层失效),但是删除元素之后的所有迭代器都无效了(第二层失效)。

deque

插入到除首尾元素之外任何位置都会导致迭代器失效(第二层失效)。如果插入到首尾元素,迭代器会失效,但是指向已存在元素的指针和引用不失效(第一层失效)。

删除除首尾元素之外的元素,所有迭代器失效(第二层失效)。如果删除的是首尾元素,首前和尾后迭代器失效,其他元素的引用、指针和迭代器不会失效。

map和set

删除和添加元素会导致内部结构调整,迭代器失效,但是引用和指针任然有效(第一层失效)。

list

添加元素不会导致迭代器失效,但是删除元素会导致删除元素后面的所有迭代器失效(第一层失效)。list删除元素永远都会导致尾后迭代器失效(第二层失效)。

三、避免迭代器失效

避免迭代器失效的几种方法:

  1. 减小迭代器的使用范围,不保存迭代器的值。
  2. 避免在遍历迭代器的过程中修改容器。
  3. 不要保存首前和尾后指针。

vector避免删除失效

在遍历vector的过程中删除元素,会导致后面的迭代器失效。如果希望删除后还能继续使用迭代器,要使用erase方法,并接收返回值作为下一个迭代器使用。

正确的使用方式:

set/map避免迭代器失效

set和map也和vector一样:

本文共执行63次查询,耗时0.334秒!
马谦马谦马谦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: