[英]C++ vector iterator: erase() last item crash
The following code checks if a ball overlaps with a brick. 以下代码检查球是否与砖重叠。 The brick is highlighted and erased from the list if the overlap occurs. 如果发生重叠,则会从列表中突出显示并删除砖块。
I am experiencing a core dump when erasing only the last item in the vector brickWall . 当我只删除矢量brickWall中的最后一项时,我遇到了核心转储。 Commenting the erase() line, the code seems to work well. 在评论erase()行时,代码似乎运行良好。
After looking through similar issues on forums, I believed I was iterating through and erasing the items in the vector properly, but I suspect it may not be the case. 在论坛上查看类似问题之后,我相信我正在迭代并正确地删除向量中的项目,但我怀疑情况可能并非如此。
Any suggestions on this code would be much appreciated! 对此代码的任何建议将不胜感激!
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);
}
}
}
The usual idiom is 通常的习语是
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;
}
}
otherwise you will be skipping elements, as well as eventually crash by going past the end. 否则你将跳过元素,并最终通过结束崩溃。
K-ballo found the mistake, and presented a good idiom, but you might find it easier to use a standard algorithm and the erase-remove idiom. 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
}
};
Now in your function: 现在你的功能:
std::vector<gdf::Entity>::iterator end_iter =
std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother));
brickWall.erase(end_iter, brickWall.end());
Or more succinctly: 或者更简洁:
brickWall.erase(std::remove_if(brickWall.begin(), brickWall.end(), Pred(ballMother)),
brickWall.end());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.