繁体   English   中英

C ++ vector iterator:erase()最后一项崩溃

[英]C++ vector iterator: erase() last item crash

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

. 当我只删除矢量的最后一项时,我遇到了核心转储。 line, the code seems to work well. 在评论行时,代码似乎运行良好。
在论坛上查看类似问题之后,我相信我正在迭代并正确地删除向量中的项目,但我怀疑情况可能并非如此。

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

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);                
        }
    }
}

通常的习语是

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;
    }
}

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

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());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM