删除容器的元素时应谨慎
来源:互联网 发布:sql中replace判断空值 编辑:程序博客网 时间:2024/05/01 22:06
当一块内存被释放后,指向它的所有指针都成了“野指针”;当容器中的的一个元素被删后,指向那个元素的所有迭代器也都失效了。这两者都是程序员的大敌。对于前者,你已经有了足够的警惕,并且多年来养成了一个对付它的好习惯,就是在释放内存后立即把指向它的指针赋值为NULL,并在使用任何指针前都先判空(判断其是否为空指针)。而对于后者,即使经验丰富的猎人也仍然不时地掉入它的陷阱。
假定我们有一个容器c,定义如下:
AssocContainer<int> c;
现在我们要删除c中包含特定值的元素,比如2012。我们最先想到的可能是循环、判断然后删除,如下:
for (AssocContainer<int>::iterator i = c.begin();i!= c.end();++i) {if (2012 == (*i)) c.erase(i);}
看起来很简单,但不幸的是,这种做法含有未定义行为,是错误的。
正如前面所述,当容器中的的一个元素被删后,指向那个元素的所有迭代器也都失效了。当c.erase(i)返回时,i已经失效。于是,for循环中的 ++i 部分将成为未定义行为。
《Effective STL》中告诉了我们一种后置递增的方法,来保证在调用erase之前就得到了c中下一个元素的迭代器。如下:
for (AssocContainer<int>::iterator i = c.begin();i != c.end();/*nothing*/ ){// for循环的第三部分是空的;i现在在下面自增if (2012 == (*i)) c.erase(i++);// 对于要删除的值,// 把当前的i传给erase,然后递增ielse ++i;// 对于其他值,直接递增i}
《Effective STL》还为我们对所有容器进行了总结。如下:
1. 去除一个容器中有特定值的所有对象:
1) 如果容器是vector、string或deque,使用erase-remove惯用法。
c.erase(remove(c.begin(), c.end(), 2012), c.end());
2) 如果容器是list,使用list::remove。
c.remove(2012);
3) 如果容器是标准关联容器,使用它的erase成员函数。
c.erase(2012);
2. 去除一个容器中满足一个特定判定式的所有对象:
比如,这个特定判定式定义如下:
bool badValue(int x) {return(x == 2012);}
1) 如果容器是vector、string或deque,使用erase-remove_if惯用法。
c.erase(remove_if(c.begin(), c.end(), badValue), c.end());
2) 如果容器是list,使用list::remove_if。
c.remove_if(badValue);
如你所见,对于序列容器(vector、string、deque和list),我们要做的只是把每个remove替换为remove_if即可。
3) 如果容器是标准关联容器,写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。
//正如我们上面讲过的。
3. 在循环内做某些事情(除了删除对象之外):
1) 如果容器是标准序列容器,写一个循环来遍历容器元素,每当调用erase时记得都用它的返回值更新你的迭代器。
for (SeqContainer<int>::iterator i = c.begin();i != c.end();){if (2012 == (*i)){// go on the Noah's Arki = c.erase(i);// 通过把erase的返回值}// 赋给i来保持i有效else++i;}
2) 如果容器是标准关联容器,写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。
for (AssocContainer<int>::iterator i = c.begin();i !=c.end();){if (2012 == (*i)){// go on the Noah's Arkc.erase(i++);// 删除元素,记得后置递增i}else ++i;}
- 删除容器的元素时应谨慎
- 删除容器的元素时应谨慎
- 容器遍历删除特定条件元素应注意迭代器的增加方式
- STL容器元素应满足的条件
- STL容器元素的删除
- 小心删除容器中元素时的迭代器失效
- 小心删除容器中元素时的迭代器失效
- 小心删除容器中元素时的迭代器失效
- 删除容器中元素时的迭代器失效问题
- STL容器删除元素的陷阱(转)
- STL容器删除元素的陷阱
- 删除顺序容器内元素的操作
- 顺序容器:删除元素的操作
- STL容器的删除元素问题
- 删除STL容器元素的方法
- 删除map容器中指定的元素
- 删除两个容器内相同的元素
- 关于容器Map删除元素的常见问题
- 学习Jsoup(一)
- WPF应用程序性能提高
- 计算地球上两点的直线距离
- Windows XP自动登陆
- 运用Maven3.0.3对项目进行管理(1)
- 删除容器的元素时应谨慎
- 按行输入的实现方法
- iframe标签的内部关闭存在一个问题(未知原因)
- 自订标签库--TagSupport详解
- RAMOS windows7 制作教程(测试成功,看原文)
- MD /MDD /ML /MT /MTD的简单介绍
- struts2.18整合json和ExtJs4.0实例
- servletContext对象
- iPad: Icon.png: icon dimensions (0 x 0) don’t meet the size requirements