【C/C++开发】STL erase()函数使用要小心
http://blog.sina.com.cn/s/blog_67b6b720010114d3.html
erase()函数的功能是用来删除容器中的元素
删除某个容器里的某个元素:c.erase(T);
看似一个简单的动作,然而对不同类型的容器,内部却做了截然不同的事情,后面介绍。
假设有这样一个题目,将某个容器中所有满足条件N == X的元素删除,按照常规的思路应该有类似这样的代码:
// 假设Container和container分别表示一种容器和对应的一个对象
Container<T>::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
if (N == X)
container.erase(it);
}
然而这样的代码对于任一种容器都是错误的
容器按内存分配方式可以分为链表容器和数组容器。
所谓的链表容器指的是一种表现方式,包括list、slist等这样基于节点的容器(动态分配内存块)和set、map、multiset、multimap等关联容器(平衡树实现),而数组容器指的是在一块连续的内存上保存元素的连续内存容器,比如vector、deque、string等。
链表容器以list为例,当执行container.erase(it)时,确实第一个满足条件的元素删除了,但这时it指针已经被删除了,它也不指向任何元素了,所以也只能到此为止了,也就是说上面的代码对于链表容器来说只能正确删除第一个满足条件的元素,针对这个问题我们首先想到的就是在删除指针之前,给其做个备份。
将这个临时变量直接建立在erase实现里,这样做更简洁,也显得专业些。
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
lt.erase(it++); //这里是关键
else
++it;
}
链表容器使用erase删除节点还有一个特点,就是会将下一个元素的地址返回,所以也可以这样实现:
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); ) {
if (*it % 2 == 0)
it = lt.erase(it);//自动返回下一个元素的地址,不用再主动前移指针
else
++it;
}
数组容器以vector为例,当执行container.erase(it)时,和上面提到的一样,第一个满足条件的元素删除了,但这时数组容器不允许中间有“空隙”,所以会做个大动作,就是将被删元素后面所有的元素前移(参考STL源码),而数组容器记录的是下标,所以删除元素后,当前下标定位的元素也就顺理成章的变成了原有队列中的下一个元素,同样以删除偶数为例,代码如下:
vector<int>::iterator it = v.begin();
for (it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0)
v.erase(it);//删除元素后,后面元素自动往前移,不用挪动指
else
++it;
}
网上有说在VS2005里面上面的v.erase(it)写法是行的 VS2008及2010却运行会出现错误 会出现
vector erase iterator outside range 最保险的做法是将v.erase(it)改成 it=v.erase(it)
【C/C++开发】STL erase()函数使用要小心的更多相关文章
- STL erase函数
1 各种迭代器erase实现 析构的基本工具 Template <class T> inline void destroy(T* pointer){ pointer->~T(); } ...
- 正确使用stl vecotr erase函数
erase函数要么删作指定位置loc的元素,要么删除区间[start, end)的所有元素. 返回值是指向删除的最后一个元素的下一位置的迭代器 Parameters All parameters ar ...
- STL中使用reverse_iterator时,如何正确使用erase函数
假设有一个list容器,顺序存储了0-9一个10个整数.现在要使用reverse_iterator迭代器来查找值为8和5的元素,并且将这两个数删除.先来看以下的解决方法: #include <i ...
- STL的erase函数和lower_bound
前提摘要: [1]一般我们的区间是左闭右开,如下面例子2. [2]erase函数谨慎使用. [3]map也是有序保存的. [erase] 1,删除字符串的首字母: string s="ecu ...
- multiset容器erase函数的误用
<从缺陷中学习C/C++>第3章库函数问题,本章主要介绍库函数的使用中会遇到的问题.使用库函数可以降低软件开发的难度,提高代码编写的效率.本节为大家介绍multiset容器erase函数的 ...
- map 和 vector 的erase函数说明
1. map的erase函数使用 这里首先要注意,C++针对map的erase函数有不同的函数原型,这往往是出现问题的关键所在.根据参考文献1: 在C++98中: (1) void erase (it ...
- Oracle数据库中调用Java类开发存储过程、函数的方法
Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日 浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...
- iOS开发之----常用函数和常数
介绍一下Objective-c常用的函数,常数变量 算术函数 [算术函数] 函数名 说明 int rand() 随机数生成.(例)srand(time(nil)); //随机数初期化int val = ...
- C++ - 容器(container)的erase()函数
容器(container)的erase()函数 本文地址: http://blog.csdn.net/caroline_wendy/article/details/23996013 容器(contai ...
随机推荐
- jpa之No property buyerOpenId found for type OrderMaster! Did you mean 'buyerOpenid'?
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...
- git基本操作及设置
$ git config --global user.name "wstmljf" $ git config --global user.email "wstmljf@1 ...
- GlusterFS Dispersed Volume(纠错卷)总结
https://blog.csdn.net/daydayup_gzm/article/details/52748812 一.概念 Dispersed Volume是基于ErasureCodes(纠错码 ...
- Codechef:Fibonacci Number/FN——求通项+二次剩余+bsgs
题意 定义 $F_n$ 为 $$F_n = \left\{\begin{matrix}0, n=0\\ 1, n=1 \\F_{n-1} + F_{n-2}, n > 1\end{matrix} ...
- zabbix server内存突然飙升
2019年10月16日22:20:58 十点二十突然内存占满,top查询一个httpd进程占了79%,查询httpd.error.log发现 [Wed Oct 16 10:24:57.578643 2 ...
- Nodejs中的模块系统
一.模块化的定义 ①具有文件作用域 ②具有通信规则:加载和导出规则 二.CommonJS模块规范 1.nodejs中的模块系统,具有文件作用域,也具有通信规则,使用require方法加载模块,使用ex ...
- 3-开发共享版APP(接入指南)-设备接入说明:使用隐藏配置
https://www.cnblogs.com/yangfengwu/p/11273226.html 该APP安装包下载链接: http://www.mnif.cn/appapk/IotDevelop ...
- 70: libreoj #2424 区间dp
$des$ $sol$ $f_{i, j, k} => a => [1, i], b => [1, j], a_i = b_j | a_i != b_j , a_i => 0 ...
- 【loj2341】【WC2018】即时战略
题目 交互题: 一开始所有点都是黑的,你需要把所有点变白: explore(u,v)会将u到v路径上的第二个点变白: 一开始只有1号点是白色的,你需要让所有点变白: 对于一条链次数限制\(O(n+lo ...
- 计蒜客 39280.Travel-二分+最短路dijkstra-二分过程中保存结果,因为二分完最后的不一定是结果 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M.) 2019ICPC西安邀请赛现场赛重现赛
Travel There are nn planets in the MOT galaxy, and each planet has a unique number from 1 \sim n1∼n. ...