vector中erase用法注意事项
2015-10-23 18:04
246 查看
以前就发现了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函数
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函数
相关文章推荐
- JS判断移动设备最佳方法
- 有哪些好用的互联网数据抓取,数据采集,页面解析工具?
- Markdown笔记
- 练习2 G题 - 数值统计
- 阿里云的9折推荐码 8DIER4
- Mysql主从搭建
- MD5 为何会算不对?
- Windows API 之 CreateThread、WaitForSingleObject(未完)
- C#使用aforge框架打开摄像头(续)
- 图像滤镜艺术---Photoshop实现Instagram之Nashville滤镜
- Android控件默认风格解析之SeekBar
- vim 设置支持鼠标
- 当bridge下接口eth0单独设置IP时,为了保证LAN PC可以连接WANPC
- 数据结构--堆栈的范例程序
- 两个数组的交集,并集,差集。
- ssl服务端没有回Server Hello
- Domain=NSCocoaErrorDomain Code=3000 没有找到有Push属性的证书 更新证书失败
- appserv中php升级问题
- 浏览器兼容问题,一直是自己最头疼,一直回避的问题,今天看得到了一些启发,发奋今天开始研究这个,哈哈,以下为转载文章,好好学习。
- 详解 clone方法