0

My game's main loop looks like this:

std::vector<std::unique_ptr<State>> states;

for(size_t i = 0; i < states.size(); i++)
{
     states[i]->Update();
     states[i]->Draw();

}

Their is a flaw with this though. I can't modify the vector (delete a state) during the iteration because if I deleted the current state the iteration is on then it breaks obviously because there is no state to call update and draw on. So I thought it would be a good idea to make a vector of states that should be added to the states vector and make a vector of states that should be deleted to the states vector. Then after the loop is over modify the states vector and no problems will occur mid iteration.

std::vector<std::unique_ptr<State>> states;
std::vector<std::unique_ptr<State>> statesToBeAdded;
std::vector<std::unique_ptr<State>> statesToBeRemoved;

for(size_t i = 0; i < states.size(); i++)
{
    states[i]->Update();
    states[i]->Draw();

}

for(size_t i = 0; i < statesToBeAdded.size(); i++)
{
    states.push_back(std::move(statesToBeAdded[i]));
}
statesToBeAdded.clear();

for(size_t i = 0; i < statesToBeRemoved.size(); i++)
{
    states.erase(std::remove(states.begin(), states.end(), statesToBeRemoved[i]), states.end());
}
statesToBeRemoved.clear(); //error is thrown here

I can't delete states from the states vector though, an error is thrown on the statesToBeRemoved.clear() line and I think it's because when I call the states.erase(...) line it deletes the element from the states vector which consequently nullifies the same element in the statesToBeRemoved vector since that element points to an object that no longer exists.

You can't just delete a std::unique_ptr without destroying what the pointer points to so I don't think there is a way to delete the element from the states vector without nullifying the element in the statesToBeRemoved vector. So how do solve this problem?

Thanks.

ProgrammerGuy123
  • 357
  • 1
  • 5
  • 12
  • 9
    Uh... it's called a **unique** pointer for a reason. You shouldn't have two of those pointing to the same thing, **ever**. Decide what your ownership semantics should be and change your pointer types accordingly. – us2012 Feb 20 '13 at 23:49
  • 5
    It looks like `statesToBeAdded` and `statesToBeRemoved` should contain just `State*` and `states` should have the `unique_ptr` instances (and therefore ownership). – Billy ONeal Feb 20 '13 at 23:51
  • do show the definition of `State`. and best, show a complete, small program that demonstrates the problem. – Cheers and hth. - Alf Feb 21 '13 at 00:03

1 Answers1

0

Different pointer types cater for different ownership semantics:

  • unique_ptrs are for unique ownership, this is why your current code does not work
  • shared_ptrs are for shared ownership - when the last shared_ptr managing an object goes out of scope, it is destroyed
  • raw pointers (*) don't really say anything about the semantics they are modeling, but you have to enforce all constraints manually - that's what makes them dangerous. They are however, safe, (and in my opinion the sensible choice) for pointers that do never have ownership of the object pointed to.

So: Your statesToBeAdded is safe as long as you can guarantee that you never have anything in there that isn't already in states. statesToBeRemoved is different: The objects are already there and in states, and it would make sense to have states take ownership of the objects - hence raw pointers would be a fair choice for statesToBeRemoved.

Note that all this is based on the few lines of code you have shown, depending on the circumstances it may well be that it makes sense to store States instead of unique_ptr<State>s in your states, etc ...

us2012
  • 16,083
  • 3
  • 46
  • 62