什么是迭代器失效?
迭代器是一种对象,可以视为高级指针,能指向数组容器中的对象。当容器发生变化时(扩容增加删除等),原来指向某个元素的迭代器不再指向该元素。这种情况一般称为迭代器失效。
vector中的情况
扩容
当对vector扩容时,会发生迭代器失效。resize自动初始化,默认为0,reverse不会初始化单纯扩展空间。vector的扩容是将原本的元素复制到新空间中,然后将原有空间清空。更换了原本的空间必然导致迭代器失效。
插入
vector的大小size和容量capacity相等时,再插入元素时,vector会自动扩展空间,一般是扩展为原来的1.5倍左右(VS中)。
1. 此时插入元素发生迭代器失效,是因为vector发生了自动扩容。
2. 提前扩好容,再插入数据不会产生迭代器失效(不在迭代器指向的地方及之前插入)3. 在迭代器指向的位置前插入,由于插入导致从迭代器指向的位置向后依次移动,导致迭代器失效。
删除
1. 删除迭代器指向的位置,迭代器失效。
2. 删除迭代器后面的位置,对迭代器没有影响,不会失效。
3. 删除迭代器前面的位置,后面的元素依次向前移动,与在迭代器位置前插入的情况类似,元素的内存位置变化,迭代器失效。
list中的情况
插入
1. 在list中迭代器指向的位置前插入一个数据,迭代器仍然指向原来的数据,不失效。(it和it2都是指向3,注释写错了。。)
原本it2指向3,在3之前插入10,it2仍然指向3。
2. 在迭代器指向的位置后插入元素,迭代器指向的元素也不改变,不失效。
原本it2指向4,在4之后插入10,it2仍然指向4。
删除
1. 直接将迭代器指向的元素删除,迭代器失效。
将it指向的3删除,直接报错。
2. 将迭代器指向元素的前面的元素删掉,不改变迭代器的指向,不失效。
原本it2指向4,删除4之前的3,it2仍然指向4。
3. 将迭代器指向元素的后面的元素删掉,也不改变迭代器的指向,不失效。
原本it2指向4,删除4之后的5,it2仍然指向4。
总结
在vector中,删除迭代器指向的元素会导致迭代器失效,删除迭代器指向的元素的前面的元素和在迭代器指向的元素前面的插入元素会导致vector的元素内部移动,迭代器会失效。手动扩容和因插入导致的自动扩容都会使迭代器失效。
在list中,删除迭代器指向的元素也会导致迭代器失效,此外其余的插入删除操作都不会改变迭代器指向的元素,迭代器不会失效。