【问题标题】:C++ vector iterator: erase() last item crashC++ 向量迭代器:erase() 最后一项崩溃
【发布时间】:2012-06-13 00:36:56
【问题描述】:

以下代码检查球是否与砖重叠。如果发生重叠,砖块会突出显示并从列表中删除。

在仅擦除矢量 brickWall 中的最后一项时,我遇到了核心转储。 注释 erase() 行,代码似乎运行良好。
在论坛上查看了类似的问题后,我相信我正在正确地迭代和擦除向量中的项目,但我怀疑情况可能并非如此。

对此代码的任何建议将不胜感激!

void Game::updateEntities()
{
    ballMother.update();
    for (std::vector<gdf::Entity>::iterator it = brickWall.begin(); it != brickWall.end(); ++it) 
    {
        if (it->getRect().intersects(ballMother.getRect())) {
            it->rect.setFillColor(sf::Color::Red);
            it = brickWall.erase(it);
        }
        else {
            it->rect.setFillColor(it->colour);                
        }
    }
}

【问题讨论】:

  • 您将 it 迭代器加倍。一次进入 for 循环,第二次进入擦除。

标签: c++ crash iterator erase


【解决方案1】:

K-ballo 发现了错误,并提出了一个很好的习语,但您可能会发现使用标准算法和擦除删除习语更容易。

struct Pred {
    Pred(const BallMother& ballMother) { 
        //save refs to whatever you need for the compare 
    }

    bool operator()(const gdf::Entity& item) {
        //collision logic here, return true if you want it erased
    }
};

现在在你的函数中:

std::vector<gdf::Entity>::iterator end_iter =
    std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother));

brickWall.erase(end_iter, brickWall.end());

或者更简洁:

brickWall.erase(std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother)),
                brickWall.end());

【讨论】:

  • 感谢您的想法科林,我会调查一下。
  • remove_if 是否以更智能的方式移动尾随元素?
  • @K-ballo 既然你提到了它,我并不肯定。我检查的所有消息来源都说它与 pred 的应用数量呈线性关系,但他们没有提到改组是如何完成的。我几乎可以想象出一种通过几次交换来做到这一点的方法,但我还没有完全弄清楚。
  • @K-ballo 我删除了关于它更快的部分,感谢您指出这一点
  • @Collin:我会看看我是否能找到任何关于它是否可以以智能方式(更快)实现的确切说法......
【解决方案2】:

通常的成语是

for (std::vector<gdf::Entity>::iterator it = brickWall.begin(); it != brickWall.end(); /*note nothing here*/) 
{
    if (it->getRect().intersects(ballMother.getRect())) {
        it->rect.setFillColor(sf::Color::Red);
        it = brickWall.erase(it);
    }
    else {
        it->rect.setFillColor(it->colour);                
        ++it;
    }
}

否则您将跳过元素,并最终通过结束而崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    相关资源
    最近更新 更多