For simplicity, I'll stick to vector<int>
but I think this applies to any vector<T>
object.
If I am using a vector<int>::iterator
to keep track of some position in a vector of int's and then I use vector<int>::push_back()
, the iterator becomes worthless. Meaning, I can't take its address with &
or dereference it. The direct reason made sense once I printed the address of some of the objects in the following sense:
vector<int> my_vec(1); //my_vec[0] = 0
vector<int>::iterator it = my_vec.begin(); //it -> my_vec[0], *it = my_vec[0] = 0
cout << "&my_vec = " << &my_vec << "\n";
cout << "&my_vec[0] = " << &my_vec[0] << "\n";
cout << "&it = " << &it << "\n"; //prints address, all good
cout << "*it = " << *it << "\n"; //prints 0, all good
cout << "\n\n" << pushing back..." << "\n\n";
my_vec.push_back(1);
cout << "&my_vec = " << &my_vec << "\n"; //same as before push_back()!
cout << "&my_vec[0] = " << &my_vec[0] << "\n"; //different from before push_back()!!
cout << "&it = " << &it << "\n"; //same as before push_back()
//cannot do &it or *it
So obviously the address of it
doesn't change but push_back()
has moved things around in memory and now the address of the different "elements" of my_vec
are changed. The fact that my_vec[i] has a new address made sense to me but then I have the following questions:
1) Why doesn't the address of my_vec
change? It seems that if push_back()
causes the addresses of the my_vec[i]
to change, it should also change the address of the whole object. For an array, my_array
is a pointer to my_array[0]
so I can imagine an operation changing the addresses of each my_array[i]
and updating the pointer to point to the new address of my_array[0]
but the address of the pointer my_array
as an object in and of itself wouldn't change. But my_vec
is not a pointer in any sense to my_vec[0]
so I am confused why the addresses of the my_vec[i]
would change but not the object my_vec
.
2) Why would any operation internal to vector<int>
that changes the address of the my_vec[i]
(such as push_back()
) not also properly "update" any iterators? This seems like a good idea? No?
3) Given that #2 is what it is and my iterators become worthless when I call push_back()
, what is the correct way to deal with this? Should I not use iterators if I need to use push_back()
? If someone is going to complain about what my use-case is for using iterators and push_back()
, I excluded it for brevity but it was basically implementing a stack using vector<int>
and I was using an iterator to keep track of the top of the stack. Since I didn't want a fixed size to start, I tried to use push_back()
to enlarge the stack when my iterator hit my_vec.end()
. But I think this is a valid question in general.
Thanks very much for your help!