Question

I fear that I am running into memory leak issues by doing the following:

(Sample code)

class myItem //random container stuff mostly. All primatives.
{
    int index;
    char* name;
    int val1;
    int val2;
};

class vecList
{

    vector< myitem* > *myVec;

    void delete()
    { 
        MyVec->erase(std::remove_if(myVec->begin(), MyVec->end(), IsMarkedToDelete), MyVec->end()); //leak here?
    }
};

Erase doesn't free the memory if it's a pointer, right? If I wasn't using remove_if, I could call delete on the pointer before destroying it. How would I do it in this case? Smart Pointers? I'd prefer not to re-implement everything with them and I don't really want to add the boost library.

Thanks!

Was it helpful?

Solution

You could just delete the item in your IsMarkedToDelete function when it returns true.

OTHER TIPS

If the only pointers to the object were in the vector, then you've leaked memory as soon as you call remove_if. remove_if moves the pointers which you are keeping down, but it doesn't say anything about the values behind the iterator it returns. Thus if you have something like [a, b, c, d] (where a, b, etc. represent different pointers), then after e = remove_if( v.begin(), v.end(), matches(b) ), your vector might (and probably will) look like [a, c, d, d], with e pointing to the second d, and all trace of b lost forever.

The obvious solution would be to use shared_ptr in the vector; this would ensure that any pointer which ended up removed from the vector would be deleted. Failing that, you can use two passes: the first would be a for_each with something like:

struct DeleteIfCondition
{
    void operator()( ObjectType* &ptr ) const
    {
        if ( condition( *ptr ) ) {
            ObjectType* tmp = ptr;
            ptr = NULL;
            delete tmp;
        }
    }
};

std::for_each( v.begin(), v.end(), DeleteIfCondition() );

as the functional object, followed by:

v.erase( std::remove( v.begin(), v.end(), NULL ), v.end() );

You can use remove_if, then for_each from the return value till the end and then erase. That would, of course, make your code a bit longer. Another possibility is to store shared_ptr pointers, if your code agrees with that.

The above is a blunt lie, as Benjamin pointed out, so you're only left with "another possibility".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top