ThemonkeyrockNL NL
ThemonkeyrockNL NL

Reputation: 1

vector, removing object trouble

I am new to c++ and am currently learning sfml.

I have set up a system that adds one 'Snowpile' object to the vector. But when I keep hitting errors like "can't increment vector past iterator past end" or that it's outside the scope.

std::vector<Snowpile*> snowpiles;

I want it to check every snowpile for the removed2 bool, and delete the ones that do have it.

for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); s_it++) {
    int sindex = std::distance(snowpiles.begin(), s_it);
    if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == false) {
        snowpiles[sindex]->melting = true;
    }
    else if (snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
        snowpiles[sindex]->melting = true;
    }
    else if (!snowpiles[sindex]->getSprite_S().getGlobalBounds().intersects(player.getSpriteP().getGlobalBounds()) && snowpiles[sindex]->melting == true) {
        snowpiles[sindex]->melting = false;
    }
    snowpiles[sindex]->meltedrem(sindex, snowpiles, m_win);
    if (snowpiles[sindex]->removed2 == true)
    {
        cout << "Detected removed 2 at " << sindex << endl;
        //delete snowpiles[sindex];
        snowpiles.erase(snowpiles.begin() + sindex - 1);
    }
        

}

The melting parts determine whether the player is on top of a snowpile. The meltdrem functions checks for bool 'melting' == true and then proceeds to start the timer. After a few seconds (+ animations) it sets the bool removed2 to true.

I know that at the program at least sees the bools changing, so thats not it.

Am I simply using vector wrong, or do I need to change something in my loop? The loop is located in the while(window.isOpen()) loop in int main.

Upvotes: 0

Views: 59

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 311176

For starters it is unclear why there is used the expression

snowpiles.erase(snowpiles.begin() + sindex - 1);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

instead of

snowpiles.erase(snowpiles.begin() + sindex);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^       

if in a comment you wrote

//delete snowpiles[sindex];

You need to increase the iterator in the for loop only when a current object was not removed.

Change the loop the following way

for (auto s_it = snowpiles.begin(); s_it != snowpiles.end(); ) {
    //...
    if (snowpiles[sindex]->removed2 == true)
    {
        cout << "Detected removed 2 at " << sindex << endl;
        //delete snowpiles[sindex];
        s_it = snowpiles.erase( s_it );
    }
    else
    {
        ++s_it;
    }
}

Upvotes: 1

Related Questions