vector删除操作 erase方法注意事项

vector使用十分方便,可以存放任意类型数据结构。有时候我们会在vector中存放对象指针等,在删除某个元素的时候,我们还需要释放相应的内存。

本文主要谈一下erase方法,尤其是在循环体中使用erase方法,需要注意是否存在隐性问题。

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()。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章