IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++】STL的迭代器失效问题 -> 正文阅读

[C++知识库]【C++】STL的迭代器失效问题

STL容器的迭代器失效问题

迭代器的作用就是让算法能够不用关心底层数据结构,其底层其实就是指针或者对指针进行封装,比如vector和string的迭代器就是原生态指针T*。因此迭代器失效就是迭代器底层对应执政指向的空间被销毁了,而使用一块已经被释放的空间,可能就会造成程序崩溃。

可能会造成迭代器失效的操作

会引起底层空间改变的操作,都可能会迭代器失效

比如:resize() reserve() insert() push_back() 等

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    vector<int> v{ 1,2,3,4,5,6 };
    auto it = v.begin();
    // 将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容
     v.resize(100, 8);
    // reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变
     v.reserve(100);
     //插入元素期间,可能会引起扩容,而导致原空间被释放
     v.insert(v.begin(), 0);
     v.push_back(8);
    while (it != v.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
    return 0;
}

如果进行以上操作,就有可能会出现空间扩容,也就是原来的空间被释放掉,数据被拷贝到了新空间,但是迭代器依旧指向的是旧空间,此时对迭代器进行操作,就会访问到已经释放的空间,所以会出现迭代器失效的报错。

请添加图片描述

指定位置元素的删除操作

erase操作也会造成迭代器失效

erase删除pos位置元素之后,pos位置之后的元素会往前挪,并不会导致底层空间的改变,理论上不会造成迭代器失效,但是当删除元素之后,当前迭代器就会指向下一个元素的位置,如果刚好删除的是最后一个位置的元素,那么当前位置迭代器就会指向下一个位置,而下一个位置是没有元素的,那么pos就会失效。所以编译器为erase做了优化,删除元素时,就会认为该位置迭代器失效。用老一点版本的编译器有可能不会优化,删除操作可能不会造成迭代器失效。

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    int a[] = { 1, 2, 3, 4 };
    vector<int> v(a, a + sizeof(a) / sizeof(int));
    // 使用find查找3所在位置的iterator
    vector<int>::iterator pos = find(v.begin(), v.end(), 3);
    // 删除pos位置的数据,导致pos迭代器失效。
    v.erase(pos);
    cout << *pos << endl; // 此处会导致非法访问
    return 0;
}

迭代器失效的解决办法

既然在进行上面的那些操作之后,迭代器的位置依旧指向旧空间。那么我们在访问迭代器之前,对它重新进行赋值,也就是更新迭代器指向的位置。那么我们再次使用就不会造成访问到非法位置的情况,迭代器失效的问题就不会出现。

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    vector<int> v{ 1,2,3,4,5,6 };
    auto it = v.begin();
     v.resize(100, 8);
     v.reserve(100);
     v.insert(v.begin(), 0);
     v.push_back(8);
     v.erase(v.begin());
    //更新迭代器
    it = v.begin();
    while (it != v.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;
    return 0;
}

请添加图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:33:09  更:2022-03-13 21:33:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:32:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码