【C++】vector的迭代器失效问题(什么是迭代器失效?那些操作会导致迭代器失效?如何避免迭代器失效?),C++中vector迭代器的失效问题详解,原因、操作与避免策略

马肤

温馨提示:这篇文章已超过439天没有更新,请注意相关的内容是否还可用!

摘要:,,本文探讨了C++中vector的迭代器失效问题。迭代器失效是指当对vector进行某些操作时,之前获取的迭代器可能变得无效,导致未定义的行为。导致迭代器失效的操作包括插入、删除元素,以及改变容器大小等。为避免迭代器失效,可以采取一些策略,如使用安全的数据结构、避免在迭代过程中修改容器内容等。了解并正确处理迭代器失效问题对于编写高效且安全的C++程序至关重要。

目录

一、前言

 二、什么是迭代器失效?

 三、哪些操作会导致迭代器失效?

四、如何避免迭代器失效?

🥝 insert迭代器失效

 ✨迭代器失效 ------ 扩容导致的野指针

 ✨迭代器失效 ------ 迭代器指向的位置意义发生改变

🍇 erase迭代器失效

 五、迭代器失效总结

六、共勉 


一、前言

        最近我们学习了 vector类 的用法和模拟实现,同时呢也提到了C++中的迭代器失效问题,在之前的文章只是简单的提了一下,由于迭代器失效问题是非常重要的,所以特地整理出来方便后期的复习和学习。如果有老铁还不太清楚 vector类 可以看看这几篇文章:
1️⃣:  vector类的使用详解
2️⃣:  vector类的模拟实现

       这篇文章的要点只有三点:1.什么是迭代器失效?2.vector那些操作会导致迭代器失效?3.如何避免迭代器失效?

 二、什么是迭代器失效?

⚡迭代器的作用:主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装

⚡vector的迭代器:就是原生态指针T*

template
typedef T* iterator;                     // 迭代器某种意义上就是指针
typedef const T* const_iterator;

⚡因此迭代器失效:实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。具体的可以用一下三步来说明:

  • [1]迭代器的本质就是指针,迭代器失效就是指针失效。
  • [2]指针失效:指针指向的空间是非法的。
  • [3]指针指向非法空间:指向了被释放的空间 或者 越界访问 。

     三、哪些操作会导致迭代器失效?

    1️⃣:所有可能会引起扩容的操作都可能会导致迭代器失效。如:resize、reserve、insert、assign、push_back等  --------------  野指针引起的迭代器失效

    2️⃣:指定位置的插入和删除都会都可能会导致迭代器失效。如: insert 、erase -----------------   迭代器指向的位置意义发生改变

    四、如何避免迭代器失效?

     接下来,我将会从 insert 和 erase 这两个接口函数来讲解如何避免 迭代器失效问题。

    🥝 insert迭代器失效

    insert迭代器失效分为两类:

    • 扩容导致野指针
    • 迭代器指向的位置意义发生改变

       下面我们先给出insert的初始版本,然后再逐渐的完善:

      • 注意:这里呢我们使用的是 vector模拟实现中的代码:vector类的模拟实现
        void insert(iterator pos, const T& x)
        {
        	//检测参数合法性
        	assert(pos >= _start && pos = pos)
        	{
        		*(end + 1) = *(end);
        		end--;
        	}
        	//把值插进去
        	*pos = x;
        	_finish++;
        }

         ✨迭代器失效 ------ 扩容导致的野指针

        •  首先我们给出以下两组测试用例:

          【C++】vector的迭代器失效问题(什么是迭代器失效?那些操作会导致迭代器失效?如何避免迭代器失效?),C++中vector迭代器的失效问题详解,原因、操作与避免策略 第1张

          • 这里为什么 push_back 尾插4个后调用insert会出现随机值?而push_back尾插5个调用insert就没有这个问题?
          •  此问题就是迭代器失效,原因就在于pos没有更新,导致非法访问野指针。

            【C++】vector的迭代器失效问题(什么是迭代器失效?那些操作会导致迭代器失效?如何避免迭代器失效?),C++中vector迭代器的失效问题详解,原因、操作与避免策略 第2张

            • 上述当尾插4个数字后,再头插一个数字发生扩容。根据reserve扩容机制,_start和_finish都会更新,唯独插入位置pos没有更新,此时pos依旧指向旧空间,reserve后会释放旧空间,此时的pos就是野指针,这也就导致后续执行*pos=x就是非法访问野指针。
              • 解决方法

                我们可以设定变量n来计算扩容前pos指针位置和_start指针位置的相对距离,最后在扩容后,让_start再加上先前算好的相对距离n就是更新后的pos指针的位置了。 

                void insert(iterator pos, const T& x)
                {
                	//检测参数合法性
                	assert(pos >= _start && pos = pos)
                	{
                		*(end + 1) = *(end);
                		end--;
                	}
                	//把值插进去
                	*pos = x;
                	_finish++;
                }

                【C++】vector的迭代器失效问题(什么是迭代器失效?那些操作会导致迭代器失效?如何避免迭代器失效?),C++中vector迭代器的失效问题详解,原因、操作与避免策略 第3张

                 ✨迭代器失效 ------ 迭代器指向的位置意义发生改变

                什么是迭代器指向的位置意义发生改变呢 ?举个例子来说明一下

                •  比如现在我要在所有的偶数前面插入2,下面我们看测试结果:
                  void test2()
                  {
                  	xas_vector::vector v1;
                  	v1.Push_back(1);
                  	v1.Push_back(2);
                  	v1.Push_back(3);
                  	v1.Push_back(4);
                  	v1.Push_back(5);
                  	v1.Push_back(6);
                  	for (auto ch : v1)
                  	{
                  		cout 

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码