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操作问题相关推荐

  1. C/Cpp / STL / vector 的 erase 会造成当前位置和之后的迭代器失效的疑问

    erase 其中一种实现 (来源:cygnus 2.91.57,github:https://github.com/xuchanglong/Cygnus-comments) iterator eras ...

  2. vector的erase失效问题

    VS和CGwin的实现效果还不一样,这里先记录下问题及解决方法.欢迎和大家一起探讨. vector容器erase操作后iterate失效真相 一.VS环境下erase代码分析 代码: for (aut ...

  3. c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件

    Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...

  4. 对vector/string执行insert/erase操作后迭代器的情况说明

    对vector/string执行insert/erase操作后迭代器的情况说明       在本文中,用字符c表示顺序容器vector和string. 1.insert()操作       常见用法: ...

  5. vector erase操作

    1.删除一个元素 先Move(_where+1),也就是将迭代器的下一个位置转化为右值,最后返回了,所以erase之后返回的是删除前的下一个位置 2.删除区间元素 注意前开后闭,剩下的没看很懂,反正最 ...

  6. C++ stl vector介绍

    转自: STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if ...

  7. STL vector的几种清空容器(删除)办法

    1.为什么需要主动释放vector内存 来自 <https://blog.csdn.net/hellokandy/article/details/78500067> vector其中一个特 ...

  8. STL vector 容器介绍

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

  9. STL vector容器

    介绍  这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用. ...

最新文章

  1. Ubuntu下非常给力的下载工具–aira2
  2. Cookie编程入门篇
  3. pytorch运行遇到的问题_如何解决吸塑机在运行中遇到真空度的问题
  4. Linux技巧:多核下绑定硬件/进程到不同CPU
  5. python爬取json数据_Python爬取数据保存为Json格式的代码示例
  6. 蓝桥杯 基础练习 时间转换
  7. Flask开发服务器
  8. Java版SLG游戏《竜退治2》
  9. [2018.07.31 T2] 第二题
  10. python语法总结
  11. 良心安利游戏音效素材网站
  12. 基于C++实现考试报名系统
  13. 【趣味科普】数学中的励志故事
  14. 奇怪问题:Hibernate 无法更新(update)
  15. 专访图麟科技联合创始人张勋:AI商用化时代,图麟科技率先抢占工业赛道
  16. 咕泡p5人工智能深度学习高薪就业5期学习
  17. Windows Terminal 自定义快捷键绑定
  18. 期货月收益率(期货收益率计算公式)
  19. 关于实现局域网内视频播放
  20. GBASE 8C——SQL参考 2 函数和操作符

热门文章

  1. 数据库-优化-数据库结构的优化-数据类型
  2. 类属性-类属性的定义及使用
  3. Activemq-In-action(二)
  4. Spring Security源码解析(一)——认证和鉴权
  5. 访问动态页面很慢 PHP,PHP动态网页程序优化及高效提速问题
  6. win10 家庭版 CredSSP加密Oracle修正 设置方法
  7. AntDB上使用表空间
  8. 多线程threading初识,线程等待
  9. IOS开发知识(二)
  10. Android SoundPool 的简单使用