STL迭代器失效的场景总结
一、序列式容器迭代器失效的场景
序列式容器以vector为例。分别有以下情况会失效:
1、push_back() 使迭代器失效。
在容器末尾添加一个元素。如果容器有剩余空间(capacity() > size()),则直接添加新元素到容器尾部。此时,原迭代器中end()会失效,其他的都不会失效。如果容器有剩余空间(capacity() < size()),会导致容器重新分配内存,然后将数据从原内存复制到新内存,再在尾部添加新元素。此时,由于内存重新分配,原迭代器(所有)都失效。
2、pop_back() 使迭代器失效。
直接将容器中的最后一个元素删除,原迭代器中end()会失效,其余的都不会失效。
3、insert(iterator, n) 使迭代器失效。
如果容器有剩余空间,先在容器尾部插入一个元素,然后将插入点及之后的元素都向后移动一位,然后在插入点创建新元素。否则,会导致容器重新分配内存,接着将插入点之前的元素复制过去,在插入点创建新元素,再将插入点之后的元素复制过去。因此 ,如果没有内存的重新分配,原迭代器中插入点及插入点之后的迭代器(包括end())都失效。如果有内存的重新分配,原迭代器(所有)都失效。
4、erase(iterator) 使迭代器失效。
将删除点及之后的元素都向前移动一位,然后删除最后一个元素。因此,原迭代器中删除点之前的迭代器都有效,删除点之后的元素迭代器都失效。
二、关联式容器迭代器失效场景
set、multiset、map、multimap, 使用红黑树来存储数据。
1、insert(iterator) 插入不会使得任何迭代器失效;
2、删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用 erase(iter++)的方式删除迭代器。