我们可以把容器看作为一个小镇。
我们可以把迭代器看作为看作为一个房子,而值看作为房子里面的人。

序列式容器

顺序容器,在内存中是一块连续的内存,当插入、删除一个元素后,内存中的数据会发生移动,以保证数据的紧凑。所以删除一个数据后,其他数据的地址发生了变化,之前获取的迭代器根据原有的信息就访问不到正确的数据。

我们可以把容器看作为一个小镇。
迭代器看作为寻找某个人的地址,也就是房子的地址。这些房子必须是连在一起的。而房子越排在前面的人越强势。

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;
}

运行报错

关联式容器