Vector subscript out of range.

closed account (2NywAqkS)
why does this generate the error "Vector subscript out of range."

1
2
3
4
5
6
7
8
for (std::vector<Grenade>::iterator it = Grenade_Vector.begin(); it != Grenade_Vector.end(); it++)
		{
			if (&*it == this)
			{
				Grenade_Vector.erase(it);
				break;
			}
		}


*This is a function in the Grenade class.

Thanks,
Rowan

Once you modify the vector, all iterators are invalidated.
Do you have other iterators to anything elsewhere in the code?
closed account (2NywAqkS)
yes, its the same code but for a different occasion. Is this what's causing it?
Possibly. Once you modify the vector, any other iterators you have from it are no longer good. You must get all new iterators...
closed account (2NywAqkS)
but if I take out the other code I still get the error.
At this point I'm really just guessing what you are doing.
Can I see more code?
Is your sample code part inside a member function of a class, be it Grenade or some other class? Creating a function this is not a good idea.
closed account (2NywAqkS)
thanks, but what would you suggest instead to do the same task?
He is removing the current object from a vector of objects. There is nothing wrong with that.
1
2
3
4
5
6
7
8
for (std::vector<Grenade>::iterator it = Grenade_Vector.begin(); it != Grenade_Vector.end(); it++)
		{
			if (&*it == this)
			{
				Grenade_Vector.erase(it);
				break;
			}
		}


This seems very, very wrong to me. The only place it would make sense is in a destructor, and a destructor for an object contained in a vector shouldn't be called until it is removed by the vector (ie. erased.)
He is removing the current object from a vector of objects. There is nothing wrong with that.
I read
*This is a function in the Grenade class.
as if he was talking about the this keyword. Whoops.
Should/shouldn't stuff assumes you know more about the code than you actually do.
Should/shouldn't stuff assumes you know more about the code than you actually do.


Things I know:

*this will have it's destructor invoked when erase is called.
The code resides in a member function of *this.

If the code resides in the destructor, the destructor will be called recursively.

If the code resides in a member function, the object will cease to exist before the member function is exited. Depending on what happens in the function, all may be well. At least, until the code changes.

One invariant that all types should have is that they exist before and after the invocation of a member function that is not a constructor or destructor. It's bad design. It shouldn't be done.

This reminds me of casting a null pointer to class type to invoke a member function that one knows doesn't access any class members. It'll probably work (until the code changes,) but it shouldn't be done.

Edit: Another thought occurs to me. It's quite possible that the destructor isn't called for this object. The next object up the line may be std::move'd to this one, and that'll make for more subtle bugs whenever they decide to show up.
Last edited on
Topic archived. No new replies allowed.