Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does push_back or push_front invalidate a deque's iterators?

As the title asks.

My understanding of a deque was that it allocated "blocks". I don't see how allocating more space invalidates iterators, and if anything, one would think that a deque's iterators would have more guarantees than a vector's, not less.

like image 231
rlbond Avatar asked May 26 '09 22:05

rlbond


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

What invalidates an iterator?

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.

Does std :: move invalidate iterators?

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

How can we avoid iterator invalidation?

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.


2 Answers

The C++ standard doesn't specify how deque is implemented. It isn't required to allocate new space by allocating a new chunk and chaining it on to the previous ones, all that's required is that insertion at each end be amortized constant time.

So, while it's easy to see how to implement deque such that it gives the guarantee you want[*], that's not the only way to do it.

[*] Iterators have a reference to an element, plus a reference to the block it's in so that they can continue forward/back off the ends of the block when they reach them. Plus I suppose a reference to the deque itself, so that operator+ can be constant-time as expected for random-access iterators -- following a chain of links from block to block isn't good enough.

like image 80
Steve Jessop Avatar answered Sep 21 '22 06:09

Steve Jessop


What's more interesting is that push_back and push_front will not invalidate any references to a deque's elements. Only iterators are to be assumed invalid.

The standard, to my knowledge, doesn't state why. However if an iterator were implemented that was aware of its immediate neighbors - as a list is - that iterator would become invalid if it pointed to an element that was both at the edge of the deque and the edge of a block.

like image 29
Drew Dormann Avatar answered Sep 20 '22 06:09

Drew Dormann