Reputation: 65
I am getting an error when I try to erase an item from an vector if the item is set to not alive by a boolean. I have tried searching the net but havn't found anything about it. I have tried to find different ways to delete elements on index x in a vector and found the function: vector.erase(vector.begin() + index)
So when I try using it in my for loop I get access violation reading location pointing at the erase function line.
Code for the loop where the error is:
if (!player.getBullets().empty())
{
for (int x = 0; x < player.getBullets().size(); x++)
{
//Check for projectiles whos status is dead.
if (!player.getBullets()[x]->getAlive())
{
//Erase the element at position x.
player.getBullets().erase(player.getBullets().begin() + x);
}
}
}
Upvotes: 0
Views: 1484
Reputation: 310910
Though the loop is invalid because counter x is increased while the size of the vector is decreased and as the result not all the vector is traversed I do not see the reason of the access violation. I think that the problem is related to objects stored in the vector.
Upvotes: 0
Reputation: 16718
It's much easier to erase correctly if you use an iterator instead of an index. An (almost) direct conversion of your code:
vector<Projectile*> bullets = player.getBullets();
for (vector<Projectile*>::iterator x = bullets.begin(); x != bullets.end(); )
{
//Check for projectiles whos status is dead.
if (!(*x)->getAlive())
{
//Erase the element at position x.
x = bullets.erase(x);
}
else
{
++ x;
}
}
Note that this only works with a local copy of the vector. If you want to update the vector in the player class itself, you will need to change getBullets
to return a reference:
vector<Projectile*> &Sprite::getBullets()
{
return bullets;
}
And then for the loop:
vector<Projectile*> &bullets = player.getBullets();
Upvotes: 0
Reputation: 476910
Don't reinvent the wheel, especially not the really difficult one that can go under water and up walls. Use a ready-made one:
#include <algorithm>
player.getBullets().erase(
std::remove_if(player.getBullets().begin(),
player.getBullets().end(),
[](Projectile * p) -> bool { return !p->getAlive(); }),
player.getBullets().end());
(I'm assuming that Bullet
is the same as decltype(player.getBullets())::value_type
, i.e. the element type of the bullets container. Adjust to suit.)
Upvotes: 2