PoundXI
PoundXI

Reputation: 121

Can't delete and erase object pointer on a vector

I need to delete and erase object pointer on a vector. I see this question Should we delete before or after erase for an pointer in the vector? but I can't erase after delete object pointer.

How to fix it? Here my code.

#include <iostream>
#include <vector>
using namespace std;

class Foo
{
public:
    class bar
    {
    public:
        Foo &_owner;
        int _id;
        bar(Foo &owner,int id) : _id(id), _owner(owner){}
        void remove()
        {
            for(vector<bar*>::iterator it=_owner.vbar.begin();it<_owner.vbar.end();it++)
            {
                if((*it)->_id == _id)
                {
                    //delete object pointer
                    delete * it;

                    //remove element
                    it = _owner.vbar.erase(it); // error on this line.
                }
            }
        }
    };
    vector<bar*> vbar;
    Foo()
    {
        // add 10 elements
        for(int i=0;i<10;i++)
            vbar.push_back(new bar(*this ,i));

        // remove element at 3
        vbar.at(3)->remove();
    }
};

int main(int argc, char *argv[])
{
    Foo foo;
    return 0;
}

[Edited] I fixed this by delete object pointer from outside Bar class(delete on Foo class) by adding no longer use bar id to vector on Foo class like this.

#include <iostream>
#include <vector>
using namespace std;

class Foo
{
public:
    class bar
    {
    public:
        Foo &_owner;
        int _id;
        bar(Foo &owner,int id) : _id(id), _owner(owner) {}
        void remove()
        {
            _owner.removeId = _id;
            _owner.removeHelper();
        }
    };
    vector<bar*> vbar;
    int removeId;
    Foo()
    {
        removeId = -1;

        // add 10 elements
        for(int i=0; i<10; i++)
            vbar.push_back(new bar(*this ,i));

        // remove element at 3
        vbar.at(3)->remove();
    }
    void removeHelper()
    {
        for(vector<bar*>::iterator it=vbar.begin(); it<vbar.end(); it++)
        {
            if((*it)->_id == removeId)
            {
                //delete object pointer
                delete * it;

                //remove element
                it = vbar.erase(it);
                break;
            }
        }
        removeId = -1;
    }
};

int main(int argc, char *argv[])
{
    Foo foo;
    return 0;
}

Upvotes: 1

Views: 2069

Answers (1)

Bo Persson
Bo Persson

Reputation: 92211

The problem is hidden here

//delete object pointer
delete * it;

which in this case is the equivalent of delete this.

After that, using any part of the current object is undefined behavior. The next round of the loop is not going to work.

Upvotes: 2

Related Questions