2

I started writing my own particle effect system for a game I'm working on in C++ and sfml. In my update method I am removing the particles which life time has expired while iterating the vector. I thought I was careful not to invalidate the iterator after erasing elements as you can see at the bottom of the method, but I'm getting the exec_bad_access code=1 or code=2. the exception always points to the erase(it) line. any ideas what might be wrong?

void ParticlesNode::updateCurrent(sf::Time dt)
{
   for(particleIterator it = _mParticles.begin(), end = _mParticles.end(); it != end;)
{
    // calculate new color RGBA
    float nr = it->color.r + it->colorDis.r * dt.asSeconds();
    float ng = it->color.g + it->colorDis.g * dt.asSeconds();
    float nb = it->color.b + it->colorDis.b * dt.asSeconds();
    float na = it->color.a + it->colorDis.a * dt.asSeconds();
    it->color = sf::Color{static_cast<Uint8>(nr),static_cast<Uint8>(ng),static_cast<Uint8>(nb),static_cast<Uint8>(na)};

    // new position
    it->pos = sf::Vector2f(it->pos.x + it->vel.x * dt.asSeconds(), it->pos.y + it->vel.y * dt.asSeconds());

    // new velocity by linear accelaration.
    float length = getLength(it->vel);
    float newLength = length + _mPData.accel * dt.asSeconds();
    float radians = cartesianToPolar(it->vel).y;

    it->vel = polarToCartesian(newLength, radians);
    // new velocity by gravity
    // new velocity by radial acceleration.


    // new remaining life time
    it->lifeSpan -= dt.asSeconds();
    if (it->lifeSpan <= 0)
       _mParticles.erase( it );
    else
        ++it;
 }
}
0

1 Answer 1

4

After erase the iterator it becomes invalid, but it's still used for the next iteration.

You should assign it by the return value of erase, which refers to the iterator following the erased element.

it = _mParticles.erase( it );

And note that not only the iterator at the point for erase becomes invalid, all the iterators after that, including end() also become invalid. So you need to evaluate end() for every iteration, i.e. change the condition of for to

for(particleIterator it = _mParticles.begin(); it != _mParticles.end();)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I tried it both ways, with assigning and without, still crashes.
hey, your second suggestion worked, I failed to re-evaluate the end iterator and that was the curlpit. thanks for straightening me out! one thing though, I don't believe it is necessary to assign it = _mParticles.erase(it); it will be there anyways. Thanks again.
@BennyAbramovici It might work with your current STL library and compiler, but better not rely on it; because the standard explicitly mentions the expected behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.