Reputation: 582
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;
}
}
Upvotes: 2
Views: 377
Reputation: 172874
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();)
Upvotes: 4