vector迭代器失效

本文探讨了迭代器在vector等容器中的核心作用,并重点剖析了resize、insert、push_back、assign等操作可能导致的迭代器失效问题。通过实例和修复方法,揭示了如何避免程序因访问已释放内存而崩溃。
摘要由CSDN通过智能技术生成

迭代器本质一个指针,或者就是对指针进行封装,那么所谓的迭代器失效也就是指针失效

指针失效:指针所指向的空间被销毁了,或者该指针成为一个野指针。

访问一个已经被释放了的空间,造成程序崩溃。

对于vector来说可能造成的迭代器失效问题:

一、所有会引起底层空间改变的操作,都有可能造成迭代器失效

resize、reverse、insert、push_back、assign

以下代码正常运行:依次打印v的各个元素

    vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };
	auto it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

 ①以下操作均有可能引起程序崩溃:

    vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };
	auto it = v.begin();

	v.resize(20, 1); // 改变v的容量大于size()的用1来填充
	v.reserve(20);	// 改变v的容量
	v.insert(v.begin(), 20, 1);	// 0号下标后插入20个1
	v.push_back(0);	//插入元素,可能会引起扩容,而导致原空间被释放
	v.assign(100, 8);	// 给vector重新赋值,可能会引起底层容量改变

	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

 对于insert()接口:

 

 原因:

        扩容的本质:开辟新空间、拷贝旧元素、释放旧空间、使用新空间

        那么在这个过程中,之前的旧空间已经被释放掉了,然而在后续打印的时候it仍然指向的是原来的已经被释放掉了的旧空间,对已经释放的旧空间进行操作,引起程序崩溃。

预防:

        在释放旧空间之后,对it迭代器进行更新。

如下:代码正常执行。

    v.assign(100, 8);	// 给vector重新赋值,可能会引起底层容量改变
	it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

二、使用erase()接口

    iterator erase(iterator position); //删除指定位置元素
	iterator erase(iterator first, iterator last);//删除指定区间元素

 删除begin()位置的元素,但是之前用it迭代器指向的就是begin()位置元素,删除之后,it指向了一块已经被释放了的空间,再次进行打印操作时就会发生程序崩溃。

    vector<int> v{ 0,1,2,3,4,5,6,7,8,9 };
	auto it = v.begin();
	v.erase(v.begin());
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

vector的删除操作不光会导致指向被删除元素的迭代器失效,删除元素后面的迭代器也会失效 

 解决:

 删除的时候使用it来进行接受,也就是对it进行重新赋值。

    it = v.erase(v.begin());

继续了解一下erase()

以下代码的功能是删除vector中所有的偶数

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    vector<int> v{ 1, 2, 3, 4, 2, 2, 6, 2, 7};
    auto it = v.begin();
    while (it != v.end())
    {
    if (*it % 2 == 0)
        it = v.erase(it);
    else
        ++it;
    }
    return 0;
}

我们发现:每当执行一次it = v.erase(it);操作,it就会指向被删除的元素的下一个元素位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值