C++ 通过导致断点的循环擦除向量中的数据
我有一个类对象(项目符号)的向量,它在大多数情况下都有效。但一旦我尝试删除项目符号,它就会循环返回,然后导致断点。“basic game.exe触发了一个断点。”我尝试了前后迭代,但总是被卡住 我使用的是SFML,对象是带有位置、旋转和大小的矩形C++ 通过导致断点的循环擦除向量中的数据,c++,visual-studio,sfml,C++,Visual Studio,Sfml,我有一个类对象(项目符号)的向量,它在大多数情况下都有效。但一旦我尝试删除项目符号,它就会循环返回,然后导致断点。“basic game.exe触发了一个断点。”我尝试了前后迭代,但总是被卡住 我使用的是SFML,对象是带有位置、旋转和大小的矩形 for (it = bullets.end(); it != bullets.begin(); it--) { it->draw(game); it->move(); if
for (it = bullets.end(); it != bullets.begin(); it--)
{
it->draw(game);
it->move();
if (it->bullet.getPosition().x > 800)
{
bullets.erase(it);
}
}
我不擅长编码,所以如果您需要其他信息,我会尝试提供。当您对向量调用erase()时,迭代器将无效。
相反,考虑一下这个:
for (auto it = bullets.begin(); it != bullets.end();)
{
it->draw(game);
it->move();
if (it->bullet.getPosition().x > 800)
{
it = bullets.erase(it);
}
else
{
it++;
}
}
您可以使用
for (auto& bullet : bullets) {
bullet.draw(game);
bullet.move();
}
bullets.erase(std::remove_if(bullets.begin(), bullets.end(),
[](const auto& bullet) {
return bullet.getPosition().x > 800;
}),
bullets.end());
从
std::vector
中删除一个元素将使其所有迭代器无效(在本例中为it
),调用未定义的行为(因为您试图在下一个循环周期中使用it-1
,it->draw(game);//访问无效迭代器
)。但有效的是项目符号。擦除(它--);但是,你必须重新考虑你的循环偶数第一it->draw(游戏)
是UB(正如它是end()
)。您可能想看看。我将代码更改为此,它工作了。谢谢,但是你能解释一下为什么这个有效而我的无效吗?@Mitchell在你调用erase之后,迭代器就失效了。erase()将迭代器返回到已擦除元素后面的元素,因此再次验证迭代器,这就是代码中发生的情况above@Kevin当然,我误读并错过了erase()
的返回用于重置它
。Downvode=>upvote。我认为您的擦除有点错误(除了是bullet::erase
而不是bullets.erase
)。你还需要给结束迭代器。@Kevin:事实上,拼写错误已经纠正了。