vector中erase用法注意事项
以前就发现了vector中的erase方法有些诡异(^_^),稍不注意,就会出错。今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.begin() 和vector.end()是变化的,因此就引入了错误的可能性。
erase的函数原型有两种形式:
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
veci.erase(iter);
}
乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。
查看MSDN,对于erase的返回值是这样描述的:An iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the vector if no such element exists,于是改代码:
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
if( *iter == 3)
iter = veci.erase(iter);
}
这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)
正确的代码应该为:
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
if( *iter == 3)
iter = veci.erase(iter);
else
iter ++ ;
}
为了避免对野指针进行操作,另一种解决方法如下:
vector<int>::iterator itor2;
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
if( *iter == 3)
{
itor2=iter;
veci.erase(itor2);
}
else
iter ++ ;
}
要解决无法删除两个连续的3的另一种方法如下:
vector<int> veci;
veci.erase(remove(veci.begin(),veci.end(),6),veci.end());
这里用到了remove()函数,
注:remove是个stl的通用算法std::remove(first,last,val)移除[first, last)范围内等于val的元素在vector里面用就类似于iter = std::remove(vec.begin(), vec.end(), val)但这个函数只是把val移到vec的末尾,并不真正删除真正删除还是要调用一次erase函数
vector中erase用法注意事项的更多相关文章
- 【转】vector中erase()的使用注意事项
vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase( iterator _Whe ...
- 转载 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法
转载自:http://www.cnblogs.com/cj695/p/3863142.html sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在 ...
- 【转】 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法
sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...
- 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法
sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...
- 【C++】从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法
sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能 ...
- vector中erase()与insert()用法
erase()用法:https://blog.csdn.net/duan19920101/article/details/50717748 注:erase是删除指定位置的元素,不能删除给定元素值.若要 ...
- vector.erase用法注意事项
转自->这里 vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(iterat ...
- vector中删除的注意事项
erase的函数原型有两种形式: iterator erase(iterator position); iterator erase(iterator first, iterator last); 例 ...
- 数据库sql中distinct用法注意事项
在写sql中去重复等操作,需要用到distinct. 在使用distinct的时候要注意,尤其是在有行列转换的时候.要把sql运行出来看看是不是与你想要的结果一样. 通过自己试验,distinct有从 ...
随机推荐
- luoguP2574 XOR的艺术
思路 01串的区间求和,区间翻转 lazy%2==0 则不用翻转,lazt%2==1则要翻转 模板题 代码 #include <iostream> #include <vector& ...
- POJ 3630 Phone List(字符串前缀重复)题解
Description Given a list of phone numbers, determine if it is consistent in the sense that no number ...
- jsp拾遗
JSP九大内置对象,七大动作,三大指令 https://blog.csdn.net/qq_34337272/article/details/64310849 JSP页面的静态包含和动态包含 https ...
- sql 之优化小技巧
SET NOCOUNT ON:不返回计数,如果存储过程中包含一些并不返回实际数据的语句,网络通信流量便会大量减少,可以显著提高应用程序性能:
- html文件引用本地js文件出现跨域问题的解决方案
在本地做个小demo,很简单,一个html文件,一个js文件,在html文件中通过<script>标签引入js,但是出现了一个意想不到的问题:浏览器报错—— 一番折腾后,终于弄明白了:加载 ...
- js与jquery对象的互转
//dom对象 var odiv = document.getElementById('box'); //dom对象转化成JQ对象, 在通过原生的方法获取到元素后,给它加上$() //$(odiv). ...
- shell until 循环
until 循环 格式: until condition do command done #输出0-9 #!/bin/bash a=0 until [ ! $a -lt 10 ] do echo ...
- 转载:oracle RAC集群启动和关闭
http://www.cnblogs.com/yhfssp/p/8184761.html oracle 11G RAC集群启动和关闭: 1.停止数据库 $srvctl stop database –d ...
- Qt5_qtconfig
1.http://tieba.baidu.com/p/3225596765 QtConfig was removed in Qt5. If you want to force Qt5 to use a ...
- Qt5_pro_01
1. QT += core gui \ sql \ #ZC: 这个对应 #include <SQL/???> (如<QtSql/QSqlDatabase><QtSql/Q ...