I found that this C++ code:
vector<int> a; a.push_back(1); a.push_back(2); vector<int>::iterator it = a.begin(); a.push_back(4); cout << *it;
print some big random number; but if you add a.push_back(3)
between 3rd and 4th lines, it will print 1. Can you explain it to me?
The C++ function std::vector::resize() changes the size of vector. If n is smaller than current size then extra elements are destroyed. If n is greater than current container size then new elements are inserted at the end of vector.
An Iterator becomes invalidate when the container it points to changes its shape internally i.e. move elements from one location to another and the initial iterator still points to old invalid location. Iterator invalidation in vector happens when, An element is inserted to vector at any location.
Iterator Invalidation in C++ When the container to which an Iterator points changes shape internally, i.e. when elements are moved from one position to another, and the initial iterator still points to the old invalid location, then it is called Iterator invalidation. One should be careful while using iterators in C++.
To avoid invalidation of references to elements you can use a std::deque if you do not insert or erase in the middle. To avoid invalidation of iterators you can use a std::list.
Edited with more careful wording
yes, resizing a vector might invalidate all iterators pointing into the vector.
The vector is implemented by internally allocating an array where the data is stored. When the vector grows, that array might run out of space, and when it does, the vector allocates a new, bigger, array, copies the data over to that, and then deletes the old array.
So your old iterators, which point into the old memory, are no longer valid. If the vector is resized downwards (for example by pop_back()
), however, the same array is used. The array is never downsized automatically.
One way to avoid this reallocation (and pointer invalidation) is to call vector::reserve()
first, to set aside enough space that this copying isn't necessary. In your case, if you called a.reserve(3)
before the first push_back()
operation, then the internal array would be big enough that the push_back
's can be performed without having to reallocate the array, and so your iterators will stay valid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With