java 迭代器失效_技术点:迭代器失效的几种情况

前言

迭代器(iterator)是一个对其执行类似指针操作的对象,我们平常理解它为一个指针,但它其实并不是我们所谓真正意义上的指针,当你sizeof查看时,会发现其所占内存并不是4字节。

迭代器是个所谓的复杂的指针,具有遍历复杂数据结构的能力。其下层运行机制取决于其所遍历的数据结构。因此,每一种容器型都必须提供自己的迭代器。

那么,大致介绍完迭代器的概念,下面来探讨下迭代器在各种容器中失效的情况,其可分为两种类型:

序列式容器迭代器失效

关联式容器迭代器失效

序列式容器迭代器失效

概述

所谓序列容器,即以线性排列(类似普通数组的存储方式)来存储某一指定类型(例如 int、double 等)的数据,例如vector、deque...等。

失效原因

当程序员对当前的元素迭代器iterator进行删除操作时,其后的所有元素的迭代器都会失效,这是因为序列式容器都是连续分配的内存空间,当对其进行erase操作时,后面的所有元素都会向前移动。【解决思路:erase返回下一个有效的iterator】

代码实现

/*-----失效代码-----*/

void vectorTest()

{

vector container;

vector::iterator iter;

for (iter = container.begin(); iter != container.end(); iter++)

{

if (*iter > 3)

container.erase(iter); // iter自增,但iter已失效

}

for (iter = container.begin(); iter != container.end(); iter++)

{

cout<

}

}

/*-----有效代码-----*/

for (iter = cont.begin(); iter != cont.end();)

{

(*it)->doSomething();

if (shouldDelete(*iter))

iter = cont.erase(iter); //erase删除元素,返回下一个迭代器

else

++iter;

}

关联式容器迭代器失效

概述

所谓关联式容器,其实就是在存储元素值的同时,还会为各元素额外再配备一个值(又称为“键”,即key),它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素,而无需再通过遍历整个容器的方式。【需要注意的是,序列式容器的元素默认是未经过排序的,而关联式容器默认是通过键值大小进行升序排序】

失效原因

对于关联容器(如map, set,multimap,multiset),删除当前的iterator,仅仅会使当前的iterator失效,只要在erase时,递增当前iterator即可。这是因为map之类的容器,使用了红黑树来实现,插入、删除一个结点不会对其他结点造成影响。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)自增方式删除迭代器。

代码实现

/*-----失效代码-----*/

void mapTest()

{

mapm;

for (int i = 0; i < 10; i++)

{

m.insert(make_pair(i, i + 1));

}

map::iterator it;

for (it = m.begin(); it != m.end(); it++)

{

if ((it->first)>5)

m.erase(it); // 此处迭代器失效,并it不能++

}

}

/*-----有效代码-----*/

for (it = m.begin(); it != m.end(); it++)

{

if (it->first==5)

m.erase(it++);

实际步骤:

it加入erase ;

然后it自增 ; // 这里it已经失效,通过++跳到下一个迭代器

然后erase执行。

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vector迭代器失效情况包括插入(insert)和删除(erase)操作。当进行插入操作时,如果插入元素导致内存重新分配,已经获取的迭代器可能会失效。因为重新分配后,原来的内存空间被释放,迭代器指向的位置就会变得无效。同样,当进行删除操作时,被删除的元素之后的所有元素都会向前移动,导致原本有效的迭代器指向错误的元素,从而失效。 举个例子,当使用erase操作删除一个元素后,被删除元素之后的所有元素会向前移动,导致原本指向这些元素的迭代器指向了错误的位置,从而失效。比如在示例代码中,当使用v.erase(it2)删除it2位置的元素后,it3原本指向下标为3的元素,但由于删除操作,它现在指向了下标为2的元素,导致输出时发生错误。 因此,要避免迭代器失效,可以采取以下措施: 1. 在进行插入或删除操作后,重新获取迭代器,而不是继续使用之前的迭代器。 2. 使用索引而不是迭代器来操作元素,因为索引不会受到元素的插入或删除操作的影响。 3. 在进行插入或删除操作之前,先判断迭代器是否有效,可以使用迭代器的成员函数进行判断,例如vector::begin()和vector::end()。 综上所述,vector迭代器失效情况主要包括插入和删除操作,为了避免迭代器失效,可以重新获取迭代器、使用索引操作元素或进行有效性判断。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vector迭代器失效分析](https://blog.csdn.net/LiangXiay/article/details/123468285)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值