首页 > 其他分享 >23迭代器失效

23迭代器失效

时间:2024-01-20 23:33:59浏览次数:25  
标签:last 迭代 iterator 23 next vec 失效

迭代器失效

  • 容器调用erase方法,当前位到容器末尾元素位置的迭代器失效,前半部分有效
  • 容器调用insert方法,当前位到容器末尾元素位置的迭代器失效,前半部分有效
  • 扩容会导致内存转移,迭代器全部失效

迭代器失效

int main()
{
	vector<int> vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	auto it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		if (*it % 2 == 0)
		{
			//insert是把it位置的元素向后移,当前位置添加新元素
			//第一次insert后迭代器就会失效
			vec.insert(it, *it - 1);
			break;
		}
	}
	it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		if (*it % 2 == 0)
		{
			//第一次erase后迭代器就会失效
			vec.erase(it);
			break;
		}
	}
}

迭代器失效的解决办法

对插入删除点的更新操作

int main()
{
	vector<int> vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	for (auto v : vec)
		cout << v << " ";
	cout << endl;
	auto it = vec.begin();
	/*for (; it != vec.end(); ++it)
	{
		if (*it % 2 == 0)
		{
			vec.erase(it);
		}
	}*/
	//for循环改写为while,记录erase时迭代器的位置
	while (it != vec.end())
	{
		if (*it % 2 == 0)
		{
			//erase时保留当前位置迭代器,并不再进行it++
			it = vec.erase(it);
		}
		else
			++it;
	}
	for (auto v : vec)
		cout << v << " ";
	cout << endl;
	//记录insert时迭代器的位置
	for (it = vec.begin(); it != vec.end(); ++it)
	{
		if (*it % 2 != 0)
		{
			//insert时保留当前位置迭代器,额外进行一次it++
			it = vec.insert(it, *it + 1);
			++it;
		}
	}
	for (auto v : vec)
		cout << v << " ";
	cout << endl;
	return 0;
}

迭代器失效的底层原理

容器底层维护了一个迭代器的链表,每个节点代表着一个迭代器,迭代器节点内包含其指向的元素位置和其所属vector指针,迭代器节点按照其指向的元素位置排序,当检查到的迭代器需要置为失效时,则该节点其所属vector指针置为null,节点被删除。

struct Iterator_Base
{
	Iterator_Base(iterator* c = nullptr, Iterator_Base* n = nullptr)
		:_cur(c), _next(n) {}
	iterator* _cur;
	Iterator_Base* _next;
};

void verify(T* first, T* last)
{
	Iterator_Base* pre = &this->_head;
	Iterator_Base* it = this->_head._next;
	while (it != nullptr)
	{
		if (it->_cur->_p >= first && it->_cur->_p <= last)
		{
			// 迭代器失效,把iterator持有的容器指针置空
			it->_cur->_pVec = nullptr;
			// 删除当前迭代器节点,继续判断后面的迭代器节点是否失效
			pre->_next = it->_next;
			delete it;
			it = pre->_next;
		}
		else
		{
			pre = it;
			it = it->_next;
		}
	}
}
iterator insert(iterator it, const T& val)
{
	// 1.不考虑扩容 2.不考虑it._p的指针合法性
	verify(it._p - 1, _last);
	T* p = _last;
	//从后方开始先依次析构
	while (p > it._p)
	{
		_allocator.construct(p, *(p - 1));
		_allocator.destroy(p - 1);
		p--;
	}
	_allocator.construct(p, val);
	_last++;
	return iterator(this, p);
}
iterator erase(iterator it)
{
	verify(it._p - 1, _last);
	T* p = it._p;
	while (p < _last - 1)
	{
		_allocator.destroy(p);
		_allocator.construct(p, *(p + 1));
		p++;
	}
	_allocator.destroy(p);
	_last--;
	return iterator(this, it._p);
}

标签:last,迭代,iterator,23,next,vec,失效
From: https://www.cnblogs.com/sio2zyh/p/17977365

相关文章

  • 代码随想录算法训练营第十天| 232.用栈实现队列 225. 用队列实现栈
    LeetCode232.用栈实现队列题目链接:232.用栈实现队列思路:用两个栈实现队列 LeetCode  225.用队列实现栈 题目链接:225.用队列实现栈 思路:一个队列对栈进行实现(实现栈中的方法) ......
  • Python实战:selenium模拟浏览器运行,获取软科网站2023中国大学排名
    Python实战:selenium模拟浏览器运行,获取软科网站2023中国大学排名在爬取一些加密的网页时,可以使用selenium模拟浏览器运行,再从网页中提取想要的数据。使用的库本文使用到的Python库有:selenium、bs4、pandas使用selenium解决网页的反爬使用bs4对html网页进行解析和提取数据......
  • CSP-S 2023 游记
    9月初开学,来到了BCMS。毕竟是新初一吗,军训还是要有的。军训期间总是隔三差五来到机房训练。现在回忆当时貌似啥也没学,可这确实是一份美好回忆,因为这段时间可以称得上我进步最快的阶段。当时可能主要去复习S初赛了吧。初赛去WFYZ考的,考场总共就那么几个人。赛时感觉过的挺......
  • 【2024潇湘夜雨】WIN11_Pro_23H2.22631.3078软件选装纯净版1.19
    【系统简介】=============================================================1.本次更新母盘来自WIN11_Pro_23H2.22631.3078。2.增加部分优化方案,手工精简部分较多。3.OS版本号为22631.3078。精简系统只是为部分用户安装,个别要求高的去MSDN下。4.集成《DrvCeo-2.15.0.5》网卡版、......
  • 昆虫科学院 AtCoder Race Ranking 2023 Autumn
    概况为提高选手们的训练/比赛热情,我们(昆虫科学院)通过商讨,在\(2023-5-25\)仿照AtCoderRaceRanking(WTF)机制,设立了“昆虫科学院AtCoderRaceRanking2023”。该排行榜为\(2023\sim2024\)赛季的第二轮排行。校内参赛选手(按照学号排序)AtCoder用户名学号......
  • Windows 11 version 23H2 中文版、英文版 (x64、ARM64) 下载 (updated Jan 2024)
    Windows11version23H2中文版、英文版(x64、ARM64)下载(updatedJan2024)Windows11,version23H2,2024年1月更新作者主页:sysin.orgWindows11目前版本所有的日期都按照ISO8601格式列出:YYYY-MM-DD)服务频道版本服务选项上市日期最后修订日期最新版本......
  • Threat Simulator (威胁仿真器) 23.12.2 - 入侵与攻击仿真(BAS)平台
    ThreatSimulator(威胁仿真器)23.12.2-入侵与攻击仿真(BAS)平台连续验证您的安全态势,有效抵御最新威胁请访问原文链接:ThreatSimulator(威胁仿真器)23.12.2-入侵与攻击仿真(BAS)平台,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgThreatSimulator威胁仿真器......
  • 触想E款工位机迭代出新,助力制造企业突围制胜!
    新品概要新年之初,触想智能上线全新E款工位机系列TPC-A14.这是一款服务于制造企业,助力生产现场数据管理及流程监控的可视化工具。TPC-A14搭载RK3399高性能处理器,集成读卡、扫码/摄像头/指示灯等典型现场应用,支持对接MES、ERP等系统拉通全面信息化管理,帮助企业降本增效。......
  • 题解 [ABC236D] Dance
    【洛谷博客】简单搜索题。题意将\(2N\)个人两两分组,每两个人配对会有一个快乐值,求快乐值异或最大。分析观察数据范围\(N\le8\),很容易想到搜索。又因为\(2N\le16\),所以直接枚举全排列不可行,需要做一点优化。第\(i\)个人和第\(j\)个人配对产生的快乐值,与第\(j\)......
  • 记一次缓存失效引发的惨案!
    对于小猫来讲,最近的一段日子是不好过的,纵使听着再有节拍的音乐,也换不起他对生活的热情。由于上一次“幂等事件”躺枪,他已经有几天没有休息好了。他感觉人生到了低谷。当接手这个商城项目之后,他感觉他一直没有好过。他的内心彷徨,在工位上边写着事故报告,边嘀咕着“今年到底是犯了啥......