I’ve been trying to debug this for almost half a day now and I just can’t seem to find the problem. Most likely what is causing the trouble is this method:
//[datamember]
std::list<Projectile*> m_Projectiles_l;
//[predicate]
bool removeDeads(Projectile* pProj) {
return !(pProj->isAlive());
}
//[the method I think might be causing the problem]
void ProjectileList::KillDeadProjectiles()
{
std::list<Projectile*>::iterator it;
it = std::remove_if(m_Projectiles_l.begin(), m_Projectiles_l.end(), &removeDeads);
if (it != m_Projectiles_l.end())
{
std::list<Projectile*>::iterator itDelete;
for (itDelete = it; itDelete != m_Projectiles_l.end(); ++itDelete) {
delete (*itDelete);
}
m_Projectiles_l.erase(it, m_Projectiles_l.end());
}
}
VS2010 break error:
Unhandled exception at 0x00389844 in PsychoBots.exe: 0xC0000005: Access violation reading location 0xfeeeff3a.
Breaking brings me to this line:
void ProjectileList::DoPhysicsStuff(const InputState& refInputState)
{
KillDeadProjectiles();
std::list<Projectile*>::iterator it;
for (it = m_Projectiles_l.begin(); it != m_Projectiles_l.end(); ++it) {
/*[THIS line]*/(*it)->DoPhysicsStuff(refInputState);
}
}
My findings:
It gives a problem when:
there are more than 2 elements in the list, and a “projectile that has been added to the list earlier than a projectile that has been
added later on” is getting removed with this method.It gives no problems when:
There is only one element in the list
OR All the elements are getting removed at the same time.
Can anyone see any errors in this?
If you need more code please comment, I tried to keep it small size for now.
You can’t rely on the contents of the container beyond the iterator returned by
remove_if. This means that you’re going to have to take a different approach if you want to manage dynamic memory in the container. The easy way is to stored shared_ptr objects instead of raw pointers. Then you can just use the remove-erase idiom and everything will be cleaned up. Otherwise you’ll need to carefully write the remove mechanism yourself instead of usingremove_if.