我们可以把容器看作为一个小镇。
我们可以把迭代器看作为看作为一个房子,而值看作为房子里面的人。
序列式容器
顺序容器,在内存中是一块连续的内存,当插入、删除一个元素后,内存中的数据会发生移动,以保证数据的紧凑。所以删除一个数据后,其他数据的地址发生了变化,之前获取的迭代器根据原有的信息就访问不到正确的数据。
我们可以把容器看作为一个小镇。
迭代器看作为寻找某个人的地址,也就是房子的地址。这些房子必须是连在一起的。而房子越排在前面的人越强势。
1. 插入元素
当我们插入一个元素时,相当于新搬入一人。如果他比所有人都弱,我们只需要新建一座房子让他排在最后就行了。
但如果他是一个很强势的人。想搬到一个已经有房子的位置(位置3),于是他把别人家房子拆掉了,重新建了一座自己喜欢的房子。而以前这个位置的人也比后面的人强,于是他把位置4的房子拆了,新建了自己的房子。而位置4当然也去拆位置5的房子。。。。。。。。。。。
于是从搬入的位置开始后面所有的房子都变了样,如果我们按照以前的地址去寻找某个人的话就再也找不到了,于是我们更新了他们的位置,也就是插入位置开始,后面所有的迭代器都失效了都需要重新更新。
#include <iostream> #include<vector> using namespace std; int main() { vector<int> v; for (int i = 1; i < 10; i++) { v.push_back(i); } auto end = v.end(); cout << *end << endl; v.insert(v.begin(), 0); //插入后end迭代器失效 cout << *end << endl; return 0; }
运行报错
2. 删除元素
当删除某个元素后,由于每个房子必须连在一起,所以后面的元素都需要向前移动位置,当移动之后所有的房子的位置也都发生了变化,删除的位置开始,所有的迭代器都失效了都需要重新更新。
删除容器中的3
int main() { vector<int> v; for (int i = 1; i < 10; i++) { v.push_back(i); } for (auto it = v.begin(); it < v.end(); it++) { if (*it == 3) v.erase(it); } return 0; }
运行报错
当删除it后 it失效,无法进行自增操作
解决方法
由于erase函数将返回下一个迭代器,所以我们可以通过接收返回值来更新迭代器
int main() { vector<int> v; for (int i = 1; i < 10; i++) { v.push_back(i); } for (auto it = v.begin(); it < v.end();) { if (*it == 3) it = v.erase(it); else it++; } for (auto i : v) cout << i << " "; return 0; }
3. 扩容
当搬进小镇的人越来越多,这个小镇的空间已经不够用了,于是小镇的所有居民都搬去了一个更大的小镇。于是他们的房子的位置都发生了改变。按照以前的地址再也找不到他们的位置了,于是我们又要进行迭代器的更新,于是所有的迭代器都需要重新更新。
int main() { vector<int> v; for (int i = 1; i < 10; i++) { v.push_back(i); } auto it = v.begin(); cout << *it << endl; v.resize(20); //手动扩容 自动扩容也会导致迭代器失效 cout << *it << endl; return 0; }