vector中删除的注意事项

本文详细解析了C++ STL中Vector容器erase方法的使用技巧及注意事项,包括如何正确删除指定元素,避免野指针问题,并介绍了remove函数配合erase方法的高效用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

例如有一个类A,

1
2
3
4
5
6
7
class A
{
public:
    int id;
    A(void);
    ~A(void);
};

定义vector<A*> vec

1
2
3
4
5
6
for (int i=0; i<10; i++)
{
    A *p = new A();
    p->id = i;
    vec.push_back(p);
}

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

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

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

那我们继续修改代码:

1
2
3
4
5
6
7
8
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自增也会出错。

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

1
2
3
4
5
6
7
8
9
10
11
12
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()     );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值