Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is vector::iterator invalidated upon reallocation?

I don't understand why a vector's iterator should be invalidated when a reallocation happens.

Couldn't this have been prevented simply by storing an offset -- instead of a pointer -- in the iterator?

Why was vector not designed this way?

like image 991
user541686 Avatar asked Jun 11 '12 00:06

user541686


People also ask

What causes iterator invalidation?

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++.

How do I fix iterator invalidation in C++?

Same as like insert or erase. All iterators and the references are invalidated if the inserted item is not inserted at the end of the deque. If the items are deleted from any of the position except the end position, then all iterators will be invalidated. Same as like insert or erase.

Does std :: move invalidate iterators?

For reference, std::vector::swap does not invalidate iterators.

What happens to iterator after insert?

For std::vector , all iterators are invalidated after calling insert if it causes the vector's size() to exceed its capacity() (i.e. it must reallocate).


2 Answers

Just to add a citation to the performance-related justification: when designing C++, Stroustrup thought it was vital that template classes like std::vector approach the performance characteristics of native arrays:

One reason for the emphasis on run-time efficiency...was that I wanted templates to be efficient enough in time and space to be used for low-level types such as arrays and lists.

...

Higher-level alternatives -- say, a range-checked array with a size() operation, a multidimensional array, a vector type with proper numeric vector operations and copy semantics, etc. -- would be accepted by users only if their run-time, space, and notational convenience approached those of built-in arrays.

In other words, the language mechanism supplying parameterized types should be such that a concerned user should be able to afford to eliminate the use of arrays in favor of a standard library class.

Bjarne Stroustrup, Design and Evolution of C++, p.342.

like image 94
Nate Kohl Avatar answered Oct 25 '22 11:10

Nate Kohl


Because for iterators to do that, they'd need to store a pointer to the vector object. For each data access, they'd need to follow the pointer to the vector, then follow the pointer therein to the current location of the data array, then add the offset * the element size. That'd be much slower, and need more memory for the size_type member.

Certainly, it's a good compromise sometimes and it would be nice to be able to choose it when wanted, but it's slower and bulkier than (C-style) direct array usage. std::vector was ruthlessly scrutinised for performance when the STL was being introduced, and the normal implementation is optimised for space and speed over this convenience/reliability factor, just as the array-equivalent operator[] is as fast as arrays but less safe than at().

like image 25
Tony Delroy Avatar answered Oct 25 '22 11:10

Tony Delroy