【问题标题】:std::list deletion of elements causing troublestd::list 删除导致麻烦的元素
【发布时间】: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


【解决方案1】:

除了remove_if 返回的迭代器之外,您不能依赖容器的内容。这意味着如果你想管理容器中的动态内存,你将不得不采取不同的方法。简单的方法是存储 shared_ptr 对象而不是原始指针。然后你可以使用 remove-erase 成语,一切都会被清理干净。否则你需要自己仔细编写删除机制,而不是使用remove_if

【讨论】:

    【解决方案2】:

    仔细阅读 std::remove_if() 的参考。 (http://www.cplusplus.com/reference/algorithm/remove_if/)

    “it”到“m_Projectiles_l.end()”范围内的值仍然有效,但其值未指定。这些值很可能没有改变,具体取决于实现。

    这样一个元素可能被包含在新列表中,并且仍然位于旧列表的末尾。删除这个元素会导致内存异常。

    您必须找到另一种方法来删除不再引用的元素。考虑智能指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多