【C++】容器的迭代器失效

这篇博客探讨了在C++中,当向不同类型的容器(如vector、deque、list)添加或删除元素时,如何导致迭代器失效的情况。详细分析了各容器在操作后迭代器、指针和引用的有效性,强调了在容器变动后重新定位迭代器的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       
向容器中添加或删除元素都有可能会使容器的迭代器失效。

       
向容器添加元素后:

(1) vector和string:若存储空间重新分配,则迭代器全部失效。若存储空间没有重新分配,则指向插入位置之前的元素的迭代器仍有效,之后的元素的迭代器将会失效。

(2) deque:插入元素到除了首尾位置之外的任何位置,都会使迭代器、指针、引用失效。插入元素到首尾,迭代器会失效,指向原来元素的指针和引用仍有效。

(3) list和forward_list:迭代器、指针、引用仍然有效。

       

在容器中删除一个元素后:

(1) vector和string:指向被删除元素之前的迭代器、引用、指针仍有效。当我们删除元素时,尾后迭代器总是会失效。

(2) deque:在首尾位置之外的任何位置删除元素,迭代器、指针、引用都会失效。如果删除的是尾元素,那么尾后迭代器失效,其他迭代器、引用、指针仍有效。如果删除的是首元素,迭代器、指针、引用仍有效。

(3) list和forward_list:指向除删除元素外的其他元素的迭代器、指针、引用仍然有效。

       

// vector、string添加元素后,若存储空间被重新分配,则指向容器的迭代器、指针、引用都失效。
// v.front()、v.back()返回的是元素的引用,类型和元素类型一样
// v.begin()、v.end()返回的元素的位置,类型是迭代器,要得到元素的值需要解引用
// v.front()、v.back()和v.begin()、v.end()都能达到访问首尾元素的效果,但它们不一样

#include<iostream>
#include<vector>
#include<sstream>
#include<forward_list>

using namespace std;
int main() {
    vector<int> v = { 0,1,2,3,4,5};       // 容器v
    vector<int> &refv = v;          // v的引用
    vector<int> *p = &v;            // v的指针
    vector<int> *refp = &refv;      // 引用的指针
    auto v_front = v.front();        // v的首元素的引用
    auto v_begin = v.begin();       // 指向v的首元素的位置
    auto v_back = v.back();          // v的尾元素的引用
    auto v_end = v.end();           // 指向v的尾元素的下一个位置
    --v_end;
    cout << "修改前"<<endl<<"v:";
    for (auto it : v) {
        cout << it<<" ";
    }
    cout << endl << endl << "refv:";
    for (auto it : refv) {
        cout << it<<" ";
    }
    cout << endl << endl << "p:" << " " << p << endl;
    cout << endl << "refp:" << " " << refp << endl;
    cout << endl << "首元素的引用v_front:" << "  " << v_front << endl;
    cout << endl << "尾元素的引用v_back:" << "  " << v_back << endl;
    cout << endl << "*v_begin:" << "  " << *v_begin << endl;
    cout << endl << "*v_end:" << "  " << *(v_end) << endl;
    // 添加元素
    v.push_back(3456789);
    cout << endl << "修改后" <<endl<< "v:" << " ";
    for (auto it : v) {
        cout << it << " ";
    }
    cout << endl << endl << "refv:";
    for (auto it : refv) {
        cout << it << " ";
    }
    cout << endl << endl << "p:" << " " << p << endl;
    cout << endl << "refp:" << " " << refp << endl;
    cout << endl << "首元素的引用v_front:" << "  " << v_front << endl;
    cout << endl << "尾元素的引用v_back:" << "  " << v_back << endl;
    cout << endl << "*v_begin:" << "  " << *v_begin << endl;
    cout << endl << "*v_end:" << "  " << *(v_end) << endl;
    system("pause");
}

在向v中添加元素后,v.front()、v.back()返回的仍是v修改前的首尾元素,而迭代器v.begin()、v.end()失效,因此每次修改容器后都必须重新定位迭代器。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
向v中添加元素后,v的元素没有失效,指针也没有改变。也许是个例?
在这里插入图片描述
在修改v后,重新定位迭代器,结果正确

 #include<iostream>
    #include<vector>
    #include<sstream>
    #include<forward_list>
    
    using namespace std;
    int main() {
        vector<int> v = { 0,1,2,3,4,5};       // 容器v
        vector<int> &refv = v;          // v的引用
        vector<int> *p = &v;            // v的指针
        vector<int> *refp = &refv;      // 引用的指针
        auto v_front = v.front();        // v的首元素的引用
        auto v_begin = v.begin();       // 指向v的首元素的位置
        auto v_back = v.back();          // v的尾元素的引用
        auto v_end = v.end();           // 指向v的尾元素的下一个位置
        --v_end;
        cout << "修改前"<<endl<<"v:";
        for (auto it : v) {
            cout << it<<" ";
        }
        cout << endl << endl << "refv:";
        for (auto it : refv) {
            cout << it<<" ";
        }
        cout << endl << endl << "p:" << " " << p << endl;
        cout << endl << "refp:" << " " << refp << endl;
        cout << endl << "首元素的引用v_front:" << "  " << v_front << endl;
        cout << endl << "尾元素的引用v_back:" << "  " << v_back << endl;
        cout << endl << "*v_begin:" << "  " << *v_begin << endl;
        cout << endl << "*v_end:" << "  " << *(v_end) << endl;
        // 添加元素
        v.push_back(3456789);
        // 重新定位迭代器
        v_front = v.front();        // v的首元素的引用
        v_begin = v.begin();       // 指向v的首元素的位置
        v_back = v.back();          // v的尾元素的引用
        v_end = v.end();           // 指向v的尾元素的下一个位置
        --v_end;
        cout << endl << "修改后" <<endl<< "v:" << " ";
        for (auto it : v) {
            cout << it << " ";
        }
        cout << endl << endl << "refv:";
        for (auto it : refv) {
            cout << it << " ";
        }
        cout << endl << endl << "p:" << " " << p << endl;
        cout << endl << "refp:" << " " << refp << endl;
        cout << endl << "首元素的引用v_front:" << "  " << v_front << endl;
        cout << endl << "尾元素的引用v_back:" << "  " << v_back << endl;
        cout << endl << "*v_begin:" << "  " << *v_begin << endl;
        cout << endl << "*v_end:" << "  " << *(v_end) << endl;
        system("pause");
    }

在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值