【发布时间】:2012-01-11 15:22:34
【问题描述】:
我已经尝试调试了将近半天,但我似乎无法找到问题所在。最有可能造成问题的是这种方法:
//[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破解错误:
Unhandled exception at 0x00389844 in PsychoBots.exe: 0xC0000005: Access violation reading location 0xfeeeff3a.
Breaking 将我带到这一行:
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);
}
}
我的发现:
在以下情况下会出现问题: 列表中有超过 2 个元素,并且一个“已添加到列表中的射弹早于已添加的射弹 稍后添加”正在使用此方法删除。
在以下情况下不会出现问题: 列表中只有一个元素 或同时删除所有元素。
任何人都可以看到其中的任何错误吗?
如果您需要更多代码,请发表评论,我现在尽量保持小尺寸。
【问题讨论】:
-
你不能使用超过
remove_if结果的迭代器。您可以擦除它们,但不能访问它们,因为不能保证它们处于任何特定状态。不过,不要再浪费时间了,不要再使用原始指针了。 -
@KerrekSB 我几乎在 cmets 中添加了“请不要使用有关智能指针的 cmets”,因为我不允许使用它们;)但我决定不这样做,因为人们喜欢制作 cmets。
标签: c++ memory-management stl std