[SOLVED] Assigning Iterator to Iterator

Started by
18 comments, last by Sanctux 14 years, 4 months ago
Oh, your problem is likely that you called cont.begin() when the container was empty. That will return you a nice invalid iterator
Advertisement
Quote:Original post by RDragon1
Oh, your problem is likely that you called cont.begin() when the container was empty. That will return you a nice invalid iterator


I'm sorry, I do not quite understand. When debugging, menuItems was populated with 2 items, and activeItem simply had (error) as a symbol and 0 as its value, and maintained that state ever since its construction in its parent class.
Jack
Did it have 2 items when you executed this:

activeItem = menuItems.begin();

?

I suspect it was .empty() at this point

If not, we'll need a full small test case that shows the problem to continue from here
Quote:Original post by RDragon1
Did it have 2 items when you executed this:

activeItem = menuItems.begin();

?

I suspect it was .empty() at this point

If not, we'll need a full small test case that shows the problem to continue from here


Why, yes.


Note the (error) symbol I mentioned.


I then experimented and look at the results:

(again the error)
Jack
I meant this line:

activeItem = menuItems.begin();

Not this line:

if( activeItem == menuItems.begin() )

- you showed the latter in the debugger
Oh, sorry.

That line is actually here:
void Menu::AddItem(MenuPair item){	menuItems.push_back(item);	if (menuItems.size() == 1)		activeItem = menuItems.begin();}
Jack
Are you absolutely sure that's always getting hit before that comparison statement gets executed?
Quote:Original post by RDragon1
Are you absolutely sure that's always getting hit before that comparison statement gets executed?


Yes.
menu.AddItem(MenuPair(PLAY, MenuItem("Play")));menu.AddItem(MenuPair(QUIT, MenuItem("Quit")));

is called in the constructor of MainMenuState, and I've stepped through the whole thing many times.

Could it be a bug on my part? I do not quite fully understand the nature of iterators.

Would posting the project help?
Jack
void Menu::AddItem(MenuPair item){	menuItems.push_back(item);	// if (menuItems.size() == 1)		activeItem = menuItems.begin();}


Try that. Iterators are invalidated when the internals of the container are moved around in memory. Adding an item to a vector for instance will re-allocate memory if the array is too small accommodate the new item, thus invalidating all previously "purchased" iterators, see below for a code sample demonstrating the problem. Possible fixes include reserve-ing some amount of menu items before hand (may cause problems later), revalidating iterators as the code above shows, using a separate container (such as std::list, which I believe does not suffer this problem), or you can simply refer to the activeItem as an index in the array.

int main() {	int* arr = new int[2]; // equivalent to vector::reserve(2)	int arrSize = 0;		arr[0] = 123; // equivalent to vector::push_back( 123 )	arr[1] = 456; // equivalent to vector::push_back( 456 )		int* selection = &arr[1];		// push_back( 789 ):	int* temp = new int[3];	for ( int i = 0; i < 2; ++i )		temp = arr;	delete[] arr;	arr = temp;	temp = 0;		arr[2] = 789;		*selection = 1; // Boom!	delete[] arr;}
Quote:Original post by _fastcall
*** Source Snippet Removed ***

Try that. Iterators are invalidated when the internals of the container are moved around in memory. Adding an item to a vector for instance will re-allocate memory if the array is too small accommodate the new item, thus invalidated all previously "purchased" iterators. Possible fixes include reserve-ing some amount of menu items before hand (may cause problems later), revalidating iterators as the code above shows, using a separate container (such as std::list, which I believe does not suffer this problem), or you can simply refer to the activeItem as an index in the array.


Oh, I see. Revalidating the iterator seems to have fixed the problem. Thanks tons, _fastcall and RDragon1.


++rating; [wink]
Jack

This topic is closed to new replies.

Advertisement