简体   繁体   中英

invalid iterator with random access iterators with deque

I am reading effective STL by Scott Meyers. Here in item 1 author is mentioning about how to choose among various containers and below is text snippet which I am having difficulty in understanding.

Would it be helpful to have a sequence container with random access iterators where pointers and references to the data are not invalidated as long as nothing is erased and insertions take place only at the ends of the container? This is a very special case, but if it's your case, deque is the container of your dreams. (Interestingly,deque's iterators may be invalidated when insertions are made only at the ends of the container. deque is the only standard STL container whose iterators may be invalidated without also invalidating its pointers and references.)

My questions on above text

  1. What does author mean by pointers and references in above context and how is it different from iterators?

  2. How deque's iterators may be invalidated when insertion made only at end and still we have valid pointers and references?

Request above two questions to be answered with simple example.

Thanks for your time and help.

For the first part, what's meant is this:

deque<int> foo(10, 1); // a deque with ten elements with value of 1
int& bar = foo.front(); // reference
int* baz = &foo.front(); // pointer
deque<int>::iterator buz = foo.begin(); // iterator
deque.push_front(0); 
// At this point bar and baz are still valid, but buz may have been invalidated

For the second part it's been covered in the detail here:

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

An iterator is often used to "cycle through" the elements of a standard-library container, much like you would do with an array index, eg in a for loop.

Iterators can be invalid for many reasons. One common case where this happens is when you use a for loop such as the following:

std::deque<int> c;

for(std::deque<int>::iterator i = c.begin(); i != c.end(); ++i) {
    // do some stuff to the deque's elements here
}

At the end of the above loop, the iterator i will point to an "element" one block after the last real element in the deque. If you tried to do something like

*i = 88;

right after the end of the above for loop that would be a problem because the container does not "own" the memory i "points" to.

But what Meyers is likely talking about is that the Standard leaves much of the implementation of a deque open to the designer. Deques are usually implemented as linked-lists of blocks of memory holding several elements, so unlike vectors there is no guarantee that elements will be next to each other in memory. Furthermore, iterators necessarily contain information about these "blocks" so that they can traverse them smoothly (ie iterators are not simply pointers).

For example, if I push_back() a new element, but there is no more room in the "last" chunk of memory, then deque will need to allocate a new block of memory for the new element (and future elements added to the end). Since an iterator I was using previously might not "know" about this new chunk of memory, it could be invalid.

References and actual pointers, on the other hand, would be used in this context to refer/point to individual objects in the container. If I write

int& j = *c.begin();

then j is a reference to the first element of c . If I then do

c.push_front(74);

j still references that previous first element, even though it is no longer at the front of the deque.

However , if you insert something in the middle of the deque, then chances are you are effectively splitting one of those contiguous chunks of memory and trying to squeeze your new element in there. To make room, elements on one side or the other must be shuffled around in memory (and possibly new memory needs to be allocated). This would by necessity invalidate pointers/references to elements on that "side" of the insertion. Since it is up to the implementer how exactly room is made for an inserted element, all bets are off with respect to any pointer/reference, no matter where it is with respect to the insertion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM