erase的函数原型有两种形式:

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

例如有一个类A,

class A
{
public:
    int id;
    A(void);
    ~A(void);
};

定义vector<A*> vec

for (int i=0; i<10; i++)
{
    A *p = new A();
    p->id = i;
    vec.push_back(p);
}

下面要删除vec中id为5的元素:

for(vector<A*>::iterator iter=vec.begin(); iter!=vec.end(); iter++)
{
    if(5 == (*iter)->id)
    {
        delete *iter;
        veci.erase(iter);
    }
}

初看这段代码没什么问题,实际上其中存在很大的问题;当调用erase方法后,iter就变成了一个野指针,继续循环iter++就出错了。

那我们继续修改代码:

for(vector<A*>::iterator iter=vec.begin(); iter!=vec.end(); iter++)
{
    if(5 == (*iter)->id)
   {
        delete *iter;
        iter = veci.erase(iter);
    }
}

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

仔细阅读上面的代码实际上也有问题,首先代码不能删除连续两个为5的元素,因为删除第一个之后,iter指向第二个,自增后,就指向了第二个后面了;其次如果元素5位于vector最后,删除后iter自增也会出错。

那么正确的写法可以如下:

for(vector<A*>::iterator iter=vec.begin(); iter!=vec.end(); )
{
    if(5 == (*iter)->id)
   {
        delete *iter;
        iter = veci.erase(iter);
    }
    else
    {
        iter++;
    }
}

这样就可以解决连续两个相同元素的问题,同时将要删除的元素位于最后的话,也不会有问题,因为删除后,erase返回vector.end()。

其实还可以采用另一种方法,在STL的算法中有一个函数remove,这个函数可以将迭代器范围内的等于某个值的元素“删除“(这里的删除是不改变容器的 大小,只是将一些不满足条件的元素前移,这样的话保留的元素都移到了容器的前面,而remove正好就指向这些保留元素后的第一个元素,而后面的就是要删 除的。)然后执行erase操作就可以了

void remove_v2(vector<int>& v,int val){
    v.erase(   remove(v.begin(),v.end(),val),       v.end()     );
}

vector中删除的注意事项的更多相关文章

  1. vector中erase用法注意事项

    以前就发现了vector中的erase方法有些诡异(^_^),稍不注意,就会出错.今天又一次遇到了,就索性总结一下,尤其是在循环体中用erase时,由于vector.begin() 和vector.e ...

  2. vector中删除第k个元素的巧妙方法

    假设我们定义了一个vector如下: vector<int> v;v.push_back(1);...v.push_back(255); 如果要删除第k个元素的话,应该这样写: (1)如果 ...

  3. 【转】java.util.vector中的vector的详细用法

    [转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...

  4. java.util.vector中的vector的详细用法

    ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.util.*; /** * 演示Vector的使用.包括Vector的创 ...

  5. 【转】vector中erase()的使用注意事项

    vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(   iterator _Whe ...

  6. vector中的元素删除

    删除vector中的元素,最容易的方法就是使用vector的erase()函数. vector vec;for ( vector::iterator iter = vec.begin(); iter! ...

  7. C++之vector中元素删除

    今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅. 预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行: c.erase(p)之后就删除了容器c中p ...

  8. 对于vector中高效删除中间元素的技巧

    众所周知,vector是连续存储空间,只提供高效的尾部删除方法pop_back() ,在中间删除的效率很低,那么如果大家想快速删除中间元素该如何实现? 话不多说,看代码: //移除vector元素,最 ...

  9. vector容器删除某些元素且释放内存

    1,size和capacity size: 指目前容器中实际有多少元素,对应的resize(size_type)会在容器尾添加或删除一些元素,来调整容器中实际的内容,使容器达到指定的大小. capac ...

随机推荐

  1. json-c开发指南

    网上看到的一片关于json-c的文章.收藏一下,忘记了出处,尽请作者谅解. JSON c语言开发指南   1.    引言 本文档是基于json-c 库对数据交换进行开发所编写的开发指南,及详细解释j ...

  2. MySQL数据库-错误1166 - Incorrect column name 'xxx' 的解决方法

    在用Navicat for MySQL给MySQL数据库修改表的字段时报如下的错误: 解决方法:检查字段里面是不是有空格,去掉就可以了.

  3. Response.cookies和Request.cookies

    Response.cookies和Request.cookies的区别很重要,由于方法基本都是差不多的,特别对于初学者而言,很容易出现混淆. 简单说就是创建cookie用response,获取cook ...

  4. HTML基础-常用标签及图片

    标记/标签{元素} 双标签: <标签>内容</标签> <html></html>    网页 页面的根元素 <head></head& ...

  5. 怎么用PHP发送HTTP请求(POST请求、GET请求)?

    file_get_contents版本: 01 /** 02 * 发送post请求 03 * @param string $url 请求地址 04 * @param array $post_data ...

  6. C++类数组的实现

    请看下面的代码: //xy_3_1 2013/10/26 #include<stdio.h> #include<iostream.h> #include<string.h ...

  7. 百度搜索URL参数含义

    序号 参数 含义 1 tn 搜索框所属网站.比如 tn=sitehao123,就是 http://www.hao123.com/ 左上那个搜索框(指通过什么方式到达百度首页搜索界面;) 2 s?wd ...

  8. C#中区别多态、重载、重写

    重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override. 格式: 基类中: public virtual void myMethod() { } 子 ...

  9. CentOS 7重装mysql8.0.15

    查看是否安装有mysql rpm -qa | grep mysql 有的话先删除干净 下载MySQL yum源 wget https://dev.mysql.com/get/mysql80-commu ...

  10. HDU 2276 Kiki & Little Kiki 2 矩阵构造

    Kiki & Little Kiki 2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...