`
ruilin215
  • 浏览: 1148921 次
  • 性别: Icon_minigender_2
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

iterator的陷阱

 
阅读更多
比如某个std::vector<x>,我们对它的一个实例对象进行遍历,找到一个元素,删除之:
std::vector<x> some_vector;
for(std::vector<x>::iterator it = some_vector.begin(); it != some_vector.end(); ++it)
{
if(...)
{
some_vector.erase(it); // 这里删除了vector的一个元素,导致it失效!!循环无法继续
}
}
想必这个错误我们都不会犯。请看下面“正确”的做法:
std::vector<x>::iterator it = some_vector.begin();
whiler(it != some_vector.end())
{
if(...)
{
std::vector<x>::iterator temp = it++; // 我们先把it保存到temp,然后移动it,使其指向下一个“有效”的元素
some_vector.erase(temp); // “放心”地删除这个元素
}
else
{
++it;
}
}
呵呵,it真的“有效”吗?真的可以“放心”删除吗?仔细想想。你会犯这个错误吗?反正我今天是犯了…… :(

一般地,对于vector这样“连续存储”(有没有想到上面的代码有什么错误?:))的容器,正确的做法是:
std::vector<x>::iterator it = some_vector.begin();
whiler(it != some_vector.end())
{
if(...)
{
some_vector.erase(it); // it失效了
it = some_vectorect.begin(); // 修正it,使其有效,然后重新开始遍历
}
else
{
++it;
}
}

类似地,在遍历过程中插入元素的情况也要仔细处理。
分享到:
评论

相关推荐

    java集合迭代器Iterator中的remove陷阱

    本篇文章将深入探讨`Iterator`中的`remove`方法以及它在`List`和`Set`集合中的陷阱。 首先,`Iterator`接口提供了一个`remove()`方法,它的作用是移除当前迭代器指向的元素。在使用`Iterator`遍历集合并删除元素时...

    [C++][经验总结]vectory迭代器(iterator)失效

    然而,一个常见的陷阱是,当我们对`vector`进行某些操作时,其迭代器可能会失效,这正是 "[C++][经验总结]vectory迭代器(iterator)失效" 这一主题的核心所在。理解这个问题对于编写稳定且高效的C++代码至关重要。 ...

    js代码-Iterator遍历对象

    在`README.txt`文件中,可能会详细解释`main.js`中`Iterator`的使用场景和具体实现,包括如何创建自定义迭代器,如何与`for...of`、`Array.from()`等方法配合使用,以及可能遇到的陷阱和注意事项。 总的来说,`...

    避坑手册 - JAVA编码中容易踩坑的十大陷阱.doc

    以下是一些在Java编码中容易出现的陷阱及其解决方法: 1. 循环中操作目标List: 当你需要在遍历List的同时删除元素时,直接使用for-each循环或者索引循环是错误的。这两种方式都会导致`...

    java中for循环删除集合陷阱

    如果必须在循环中进行增删改操作,可以考虑使用迭代器或者`Iterator.remove()`方法,这能更安全地处理集合的动态变化。同时,理解集合遍历和修改之间的交互是避免这类陷阱的关键。在实际编程中,应尽可能遵循最佳...

    突破程序员基本功的16课.part2

    3.4 Iterator迭代器 迭代时删除指定元素 3.5 小结 第4课 Java的内存回收 4.1 Java引用的种类 4.1.1 对象在内存中状态 4.1.2 强引用 4.1.3 软引用 4.1.4 弱引用 4.1.5 虚引用 4.2 Java的内存泄漏 4.3 垃圾...

    关于STL的erase()陷阱-迭代器失效问题的总结

    std::list&lt;int&gt;::iterator itList; for (itList = List.begin(); itList != List.end(); ) { if (WillDelete(*itList)) { itList = List.erase(itList); } else { itList++; } } ``` - **正确写法2**:在...

    Effective STL

    优先使用`iterator`而非`const_iterator`、`reverse_iterator`和`const_reverse_iterator`(Prefer iterator to const_iterator, reverse_iterator, and const_reverse_iterator)** - **概述**:在可能的情况下...

    Effective_STL英文版

    书中详细讲解了STL使用中的最佳实践和陷阱,为读者提供了50条指导原则。在本书中,作者不仅仅提供了规则,还给出了详细的分析和实例,让读者明白何时何地怎样使用STL,以及这样做的原因。 ### 容器使用原则 1. ...

    浅谈foreach写失效的问题

    在 Java 编程中,foreach 循环是非常常用的遍历集合元素的方式,但是很多开发者在使用 foreach 循环时,容易掉入一个非常容易忽视的陷阱,即在 foreach 循环中,无法直接修改集合元素的值。 问题的根源在于,...

    effective stl 中文 pdf

    书中详细讲解了如何有效地使用STL中的容器、迭代器、算法和函数对象,以及如何避免常见的陷阱和误区。本书针对的读者是已经熟悉C++语言并希望深入掌握STL的专业程序员。 在这份文件中,列出了书籍中的若干要点,...

    zzbd.rar_正则表达式_正则表达式c++

    8. **正则表达式陷阱** - 避免使用贪婪匹配,可能导致不必要的大范围匹配。使用非贪婪量词?来限制匹配。 - 注意正则表达式中的顺序,因为它们是左到右解析的,可能导致意料之外的结果。 9. **扩展应用** - 在...

    python中函数常见坑

    然而,初学者在使用函数时可能会遇到一些常见的“坑”,这些陷阱往往与局部变量作用域和迭代器的使用有关。本篇文章将深入探讨这两个主题,并提供解决方案。 **一、局部变量作用域** 在Python中,变量的作用域分为...

    正确用法Java大事通知_.docx

    在Java编程中,事件通知机制是一种常用的设计模式,用于...通过以上分析,我们可以看到,即使是最简单的事件通知机制,也可能隐藏着一些潜在的陷阱。在实际开发中,我们需要仔细设计和实现,确保代码的健壮性和性能。

Global site tag (gtag.js) - Google Analytics