C++迭代器失效问题

在C++中迭代器失效是个常见的问题,通常有两种情况的迭代器失效问题

1.容器扩容,迭代器失效

例1:模拟实现vector容器的insert函数时,函数原型为

void insert(iterator position, const T& val)

如果容器发生扩容,则需要开辟新空间,将旧空间数据拷贝到新空间中,最后销毁旧空间。而迭代器position始终没有改变,仍然指向旧空间中的某个位置,从而导致程序bug。

如何解决?如果容器发生扩容,则更新迭代器。

//insert
void insert(iterator position, const T& val)
{
	assert(position <= _finish);
	assert(position >= _start);
	size_t len = position - _start;//2.迭代器失效问题,如果发生扩容,position还是指向原来的空间位置,是野指针,需要更新position的位置
	//扩容
	if (size() == capacity())
	{
		reserve(capacity() == 0 ? 4 : 2 * capacity());
	}
	position = _start + len;//更新position位置
	//挪动数据
	iterator end = _finish;
	while (end > position)
	{
		*end = *(end - 1);
		--end;
	}
	//插入数据
	*position = val;
	++_finish;
}

例2:容器扩容,迭代器失效,具体要看容器的扩容方式,只有当容器扩容时迭代器才会失效。也就是说正常push数据时迭代器可能失效,因此我们要及时更新迭代器。

如果容器是二倍扩容,初始时空间为4,那么当插入第5个数据时,容器需要扩容,迭代器即失效

迭代器it已经失效,未更新不能继续使用(VS编译器下无论迭代器是否失效,只要未更新就不能使用)

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
auto it = v.begin() + 3;
v.insert(it, 9);
cout << *it << endl;

vector容器在编写insert函数时设置的函数返回值为迭代器指向当前插入位置,目的就是为了提供更新迭代器的接口,防止迭代器失效

正确修改:更新迭代器it再使用

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
auto it = v.begin() + 3;
it= v.insert(it, 9);
cout << *it << endl;

2.数据变动,迭代器失效

例如利用迭代器删除vector容器中的偶数(数据为:0 2 4 6 8 9 )

it指数据0位置,0为偶数,删除该数据,此时后面所有数据前移,数据0位置数据被2替代,此时迭代器it++,指数据4位置,跳过了数据2,因而程序出现bug

vector<int>::iterator it = v.begin();
while (it != v.end())
{
    if (*it % 2 == 0)
        v.erase(it);
    ++it;
}

其实当erase删除数据时,此时迭代器就已经失效了,不能进行++(VS2022编译器下直接报错)

如何解决?每次删除数据即更新迭代器

vector<int>::iterator it = v.begin();
while (it != v.end())
{
    if (*it % 2 == 0)
        it = v.erase(it);
    else
        ++it;
}

综上所述,解决迭代器失效问题的有效方法就是:及时更新迭代器

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南林yan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值