Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Vector Iterator Outside Range

This thread is locked; no one can reply to it. rss feed Print
Vector Iterator Outside Range
Ron Rider
Member #8,208
January 2007

In my game I have a vector of strings for and I am trying to delete one of items from the list. I am using the following .erase() function in my program:

Player.GetPotions().erase( (Player.GetPotions().begin() + battle_use_potion_dialog[0].d1) );

The code compiles fun, but when I run my program I get a Debug Assertion Error saying

Quote:

vector erase iterator outside range

I have outputted Player.GetPotions().begin(), battle_use_potion_dialog[0].d1, and the sum of both; all three equal 0. How can 0 be out of range? I have tried creating an iterator and used that, but that only created more problems on top of the one I have now. I have used vectors and the erase method before, and when I compare this line of code with my others I do not see a difference.

Hard Rock
Member #1,547
September 2001
avatar

Without really checking what I'm about to say, is there any chance that there are no potions, so that Player.GetPotions.begin() == Player.GetPotions.end() and is therefore out of range?

_________________________________________________
Hard Rock
[ Stars Dev Company ][ Twitter ][Global Warming: ARA My TINS 07 Entry][Pong Ultra Website][GifAllegS Ver 1.07]
"Well there's also coolwebsearch but we'll let that be an IE exclusive feature" - arielb on the New Browser Plugins "What's better, HTML or Variables?"

spellcaster
Member #1,493
September 2001
avatar

Chances are that deleting the potion invalidates your iterator. There are several ways to deal with this, like switching the iterator used or using the return value of the delete function... it depends on what collection library you're using.

--
There are no stupid questions, but there are a lot of inquisitive idiots.

Ron Rider
Member #8,208
January 2007

Hard Rock - That line of code never gets run when there isn't a potion in the Potion bag. And I have checked to make sure that there is indeed a potion.

spellcaster - When you say my iterator, are you talking about me using Player.GetPotions().begin()? What other iterator could I use? And wouldn't using the .erase() function's return value involve me actually erasing an item?

Hard Rock
Member #1,547
September 2001
avatar

There are two tricks to deleting items when using STL iterators.

1)Delete in reverse order. So delete from back to front. If you do this you will have no problems

2)Example code otherwise

//it = the iterator
while(it!= itemlist.end())
{
  if(wewanttodeletethisitem)
  {
  it = itemlist.erase(to); //increments iterator to next valid spot
  }
  else
  {
  ++it; //keep checking
  }

_________________________________________________
Hard Rock
[ Stars Dev Company ][ Twitter ][Global Warming: ARA My TINS 07 Entry][Pong Ultra Website][GifAllegS Ver 1.07]
"Well there's also coolwebsearch but we'll let that be an IE exclusive feature" - arielb on the New Browser Plugins "What's better, HTML or Variables?"

Ron Rider
Member #8,208
January 2007

After examining my old code, I realized that Player.GetPotions() is a method that only lets me read the vector. Does that sound right? I have .GetPotions() set as a "getter" method and will only return the potions vector. I am assuming this is why the iterator will always be outside the range.

I created a new vector and assigned it the Player's existing potions vector. Then I erased the potion from the newly created vector and then re-assigned the Player's potions to the newly manipulated vector.

I checked the runtime, and everything worked fine; but, is doing the above safe or is it bad programming practice?

Indeterminatus
Member #737
November 2000
avatar

Quote:

[...] is doing the above safe [...]?

Yes, it is, assuming you don't keep any pointers (or references, or iterators) to elements in the original collection (because these would be invalidated).

Actually, you will find in several books that such atomic behaviour of a method is good practice. While I don't want to rally this point, take it with a grain of salt. Copying, modifying and assigning can be a very costly operation, and depending on the circumstances, the pros of a method's atomicity (?) do not outweigh the costs.

Quote:

After examining my old code, I realized that Player.GetPotions() is a method that only lets me read the vector. Does that sound right?

Only if Player.GetPotions() returns a const_iterator const std::vector &. If that were the case, however, you ought not be able to invoke erase on its return value, as erase is no const method.

edit: Fixed an error.

_______________________________
Indeterminatus. [Atomic Butcher]
si tacuisses, philosophus mansisses

Go to: