STL vector的erase操作问题
STL vector的erase操作问题
一老大说CSDN上有篇博文(“关于STL vector的erase操作”,地址是:http://blog.csdn.net/tingya/archive/2007/12/28/1998442.aspx)黑奇怪,抱着猎奇的心态,偶也去凑哈热闹,发现了一点问题,报告给大家。
作者说下面的代码是错误的:
vector<unsigned short> m_UintVector;
m_UintVector.push_back(10);
m_UintVector.push_back(20);
m_UintVector.push_back(30);
vector<unsigned short>::iterator itr;
itr = std::find(m_UintVector.begin(), m_UintVector.end(), 20);
m_UintVector.erase( itr);
作者给出了“正确”的代码:
vector<unsigned short> m_UintVector;
m_UintVector.push_back(10);
m_UintVector.push_back(20);
m_UintVector.push_back(30);
vector<unsigned short>::iterator itr;
itr = std::find(m_UintVector.begin(), m_UintVector.end(), 20);
//删除元素
int diff = itr - m_UintVector.begin();
m_UintVector.erase( m_UintVector.begin() + diff );
我倒没看到“正确”的代码高明在哪里?姑且不考虑代码是否正确,从代码量来看,明显增加了;从代码的通用性来看,iterator + diff 这样的代码只适用随机迭代器,对list, map等等非随机类型的迭代器是不能使用的。我觉得第一种写法更漂亮通用。至于代码的正确性,我测试过,工作得很好。
我猜想作者这里应该没有完整描述真实的工作环境,应该还有一些限制条件没有列出来,我google了一下,发现了下面的情况:
void main()
{
vector<int> member;
member.push_back(1);
member.push_back(2);
member.push_back(2);
member.push_back(3);
member.push_back(1);
member.push_back(2);
member.push_back(4);
vector<int>::iterator iter;
for(iter = member.begin();
iter != member.end();iter++)
cout<<*iter<<endl;
cout<<"do erase--------"<<endl;
for(iter = member.begin();
iter != member.end();iter++)
{
if(*iter == 2)
{
member.erase(iter);
}
}
for(iter = member.begin();
iter != member.end();iter++)
cout<<*iter<<endl;
}
乍一看,这不是和上面提到的第一种方法一样吗?貌似没有问题啊。可是,要注意到,调用erase后,回到for循环又继续使用迭代器,并执行++运算。
好,让我们再温习一下erase函数的说明:
iterator erase ( iterator position );
iterator erase ( iterator first, iterator last );
现在我们只关注函数执行后的副作用和返回值。函数调用后使指向position和first之后的所有迭代器失效。返回值则是一个指向删除的最后一个元素后面的元素的迭代器。所以上面代码中的iter在调用erase后就无效了,我在VS2005中测试了,确实崩溃在++的操作上。
要解决这个问题,我们只需弃用原来的迭代器,使用返回值即可,代码如下:
for(iter = member.begin(); iter != member.end();)
{
if(*iter == 2)
{
iter = member.erase(iter);
}
else
{
iter++;
}
}
网络上还有很多这样的文章都没太讲清楚,比如“如何删除std::vector内的element?”http://www.cnblogs.com/oomusou/archive/2006/11/15/561204.html一文中说:若要删除std::vector中的element,正规的方式该用find() generic algorithm,若find()找到了,会传回该iterator,若找不到,将传回vector.end()。这种写法远比用for loop干净很多。
看他给出的代码:
// Compile OK, but run-time error!!
// for(std::vector<int>::iterator iter = ivec.begin();
// iter != ivec.end(); ++iter) {
// if (*iter == 8) {
// ivec.erase(iter);
// }
// }
// This is a RIGHT way to do it.
std::vector<int>::iterator iter = find(ivec.begin(), ivec.end(), 8);
if (iter != ivec.end()) {
ivec.erase(iter);
}
所以,网络上的文章看看就是了,最好是当作小说来看,猎奇一下别人的技术人生,至于是否真实是否正确,不要当真了,否则下一代堂吉诃德就要诞生了,呵呵。
STL vector的erase操作问题相关推荐
- C/Cpp / STL / vector 的 erase 会造成当前位置和之后的迭代器失效的疑问
erase 其中一种实现 (来源:cygnus 2.91.57,github:https://github.com/xuchanglong/Cygnus-comments) iterator eras ...
- vector的erase失效问题
VS和CGwin的实现效果还不一样,这里先记录下问题及解决方法.欢迎和大家一起探讨. vector容器erase操作后iterate失效真相 一.VS环境下erase代码分析 代码: for (aut ...
- c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件
Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...
- 对vector/string执行insert/erase操作后迭代器的情况说明
对vector/string执行insert/erase操作后迭代器的情况说明 在本文中,用字符c表示顺序容器vector和string. 1.insert()操作 常见用法: ...
- vector erase操作
1.删除一个元素 先Move(_where+1),也就是将迭代器的下一个位置转化为右值,最后返回了,所以erase之后返回的是删除前的下一个位置 2.删除区间元素 注意前开后闭,剩下的没看很懂,反正最 ...
- C++ stl vector介绍
转自: STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if ...
- STL vector的几种清空容器(删除)办法
1.为什么需要主动释放vector内存 来自 <https://blog.csdn.net/hellokandy/article/details/78500067> vector其中一个特 ...
- STL vector 容器介绍
介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...
- STL vector容器
介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用. ...
最新文章
- Ubuntu下非常给力的下载工具–aira2
- Cookie编程入门篇
- pytorch运行遇到的问题_如何解决吸塑机在运行中遇到真空度的问题
- Linux技巧:多核下绑定硬件/进程到不同CPU
- python爬取json数据_Python爬取数据保存为Json格式的代码示例
- 蓝桥杯 基础练习 时间转换
- Flask开发服务器
- Java版SLG游戏《竜退治2》
- [2018.07.31 T2] 第二题
- python语法总结
- 良心安利游戏音效素材网站
- 基于C++实现考试报名系统
- 【趣味科普】数学中的励志故事
- 奇怪问题:Hibernate 无法更新(update)
- 专访图麟科技联合创始人张勋:AI商用化时代,图麟科技率先抢占工业赛道
- 咕泡p5人工智能深度学习高薪就业5期学习
- Windows Terminal 自定义快捷键绑定
- 期货月收益率(期货收益率计算公式)
- 关于实现局域网内视频播放
- GBASE 8C——SQL参考 2 函数和操作符