迭代器失效的原理是什么

枯南阁 2012-05-13 11:18:51
对于vector容器,假设有迭代器it1指向容器中第三个元素,it2指向第四个元素。那么,现在我用erase(it1)删除第三个元素,为什么it1,it2会失效呢。
我是这样想的,当第三个元素被删除时,it1指向的的地址 存储了移上来的第四个元素,it2指向了移上来的第五个元素。但事实是,it1,it2和指向之后元素的迭代器都失效了;那我就不能懂了,我的想法是建立在vector是连续存储的基础上的。
求解释。

还有deque容器为什么可以在首尾部不断的插入,而不会有重新加载的问题。

两个疑惑,求解释
...全文
578 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
mars_man 2012-05-15
  • 打赏
  • 举报
回复
vector内部的存储管理策略决定了这种想法是靠不住的,况且不同的实现可能策略都不一样。

另外标准也说明了这一点,删除了元素导致迭代器失效的问题。
rendao0563 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

引用 3 楼 的回复:
你用啥编译器

用VS2005没问题


vs2008啊 这跟编译器有关系吗
[/Quote]

上面已经解释了.
iamnobody 2012-05-14
  • 打赏
  • 举报
回复
后面的迭代器不再指向原来的元素,所以失效.

不只是迭代器,还有引用(包括指针)都会失效.
pathuang68 2012-05-14
  • 打赏
  • 举报
回复
“假设有迭代器it1指向容器中第三个元素,it2指向第四个元素。那么,现在我用erase(it1)删除第三个元素”
erase(it1)的返回值是一个迭代器,就是被删元素(第三个元素)后面那个元素。

迭代器之所以失效,是因为vector中存储的元素的内存发生了移动。
枯南阁 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
似乎只要迭代器所指的值变了就会失效
而不在于迭代器可不可以取值
[/Quote]

那我修改第三个元素 *it1=*it1*2,这样迭代器也不会失效的啊
ljhhh0123 2012-05-14
  • 打赏
  • 举报
回复
标准规定vector时空间不必是连续的和固定的。
zhangsongcui 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

似乎只要迭代器所指的值变了就会失效
而不在于迭代器可不可以取值
[/Quote]
请无视这个orz
zhangsongcui 2012-05-14
  • 打赏
  • 举报
回复
似乎只要迭代器所指的值变了就会失效
而不在于迭代器可不可以取值
枯南阁 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
“假设有迭代器it1指向容器中第三个元素,it2指向第四个元素。那么,现在我用erase(it1)删除第三个元素”
erase(it1)的返回值是一个迭代器,就是被删元素(第三个元素)后面那个元素。

迭代器之所以失效,是因为vector中存储的元素的内存发生了移动。
[/Quote]
也就是说,不是简单的就是第四个元素的值copy到上一个元素的内存中存储

那你说的“存储的元素的内存发生了移动”是什么意思
zhangsongcui 2012-05-14
  • 打赏
  • 举报
回复
vec.erase(std::copy/*move*/(iter+1, vec.end(), iter), vec.end());
kakarot23 2012-05-14
  • 打赏
  • 举报
回复
你用啥编译器

用VS2005没问题
枯南阁 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
你用啥编译器

用VS2005没问题
[/Quote]

vs2008啊 这跟编译器有关系吗
kakarot23 2012-05-14
  • 打赏
  • 举报
回复
空间必须连续,但可以不固定


[Quote=引用 7 楼 的回复:]

标准规定vector时空间不必是连续的和固定的。
[/Quote]
cash1943 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

vector擦除就是把后面的数据移动到前面来。所以他们所指的内容肯定是一样了嘛。还有这个是看STL实现的,要具体问题具体分析了。
[/Quote]大善
W170532934 2012-05-14
  • 打赏
  • 举报
回复
vector擦除就是把后面的数据移动到前面来。所以他们所指的内容肯定是一样了嘛。还有这个是看STL实现的,要具体问题具体分析了。
King边 2012-05-14
  • 打赏
  • 举报
回复
vector吧你都知道了被删除的后面元素的迭代失效了 不难理解后面所有的迭代都失效了,
deque呢 应该和vector分配内存方式一样 只是在首尾都预约了内存空间,所以在首尾插入就是插入约定的空间里的 所以不会重新加载,但是如果预约内存被用完了,它就要重新分配内存了(本人根据vector猜想,有错请指教)
mars_man 2012-05-14
  • 打赏
  • 举报
回复
只想说说deque的问题,这个问题应该去找本STL剖析之类的书,因为这个问题是在讨论STL的内部实现了。
某大一菜鸟 2012-05-14
  • 打赏
  • 举报
回复
这跟容器的数据结构有关..
wsxxiaohao 2012-05-14
  • 打赏
  • 举报
回复
你移动了数据,里面的迭代器肯定会失效的嘛
loongee 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
引用 3 楼 的回复:
你用啥编译器

用VS2005没问题


vs2008啊 这跟编译器有关系吗
[/Quote]

跟编译器是有关的,不同的编译器对STL的实现方法不一样。
在VS2010,DEBUG模式下,当你调用erase时,从erase函数中的起点参数到VECTOR终点的iterator将被标记为无效(即使没有发生内存移动,它们也其实确实指向了被移动过来的后续元素,而且这些元素的地址也是有效的)。而在对iterator进行解引用时,DEBUG模式下的错误预防代码便会对iterator有效性进行检查,此时程序就无法继续运行了。

如果使用RELEASE模式,将VS的STL中的错误预防代码屏蔽掉,你的it1就可以拿到后续的值了,但是这种违规做法是极力不推荐的。
加载更多回复(2)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧