Innkeeper
Innkeeper

Reputation: 673

Safely erasing from vector of pointers

Ok, this is probably pretty basic, but I've never done it before.

I have a vector of Particles, and when they leave the visible screen, I want to erase them. I looked up the erase-remove idiom, but I don't know how to make that work, because I also need to delete the Particle instances. I tried with backwards iteration, without success:

for ( std::vector<Particle*>::reverse_iterator rit = particles.rbegin(); rit != particles.rend(); ++rit )
{
    if ( IsOffScreen((*rit)->pos) )
    {
        delete (*rit.base());
        particles.erase(rit.base());
    }
}

At runtime crash, Visual Studio says "iterator cannot be decremented". What am I doing wrong? Is there a better way?

Upvotes: 1

Views: 405

Answers (1)

Peter
Peter

Reputation: 7324

What about:

for (std::vector<Particle*>::iterator it = particles.begin(); it != particles.end(); ++it) {
    if (IsOffScreen((*it)->pos)) {
        delete *it;
        *it = NULL;
    }
}
particles.erase(std::remove(particles.begin(), particles.end(), NULL), particles.end());

There are various other options - you could actually delete them in the predicate, for example, since IIRC it's guaranteed to be run exactly once on each item.

You do need to be careful with remove and remove_if for this kind of thing, since the removed objects are left in undefined state, so it's not possible to remove them and delete afterwards (you can use std::partition for that, but it's slower).

Upvotes: 1

Related Questions