Pointers to items in the container

Let's say I have an object:

struct Foo { int bar_; Foo(int bar) bar_(bar) {} }; 

and I have an STL container containing Foo s, possibly a vector, and I take

 // Elsewhere... vector<Foo> vec; vec.push_back(Foo(4)); int *p = &(vec[0].bar_) 

This is a terrible idea, isn't it?

The reason is that vector will store its elements in a dynamically allocated array somewhere, and ultimately, if you add enough elements, it will have to select another array, copy all the elements of the original array, and delete the old array. After that, p points to garbage. This is why many vector operations will invalidate iterators.

It would seem reasonable to assume that the operation, which will invalidate the iterators from the container, will also invalidate the pointers to the data elements of the container elements, and that if the operation does not invalidate the iterators, these pointers will still be safe. However, many reasonable assumptions are false . Is this one of them?

+4
source share
4 answers

The standard indicates when such pointers are invalid. vector links die when you increase size over past capacity or add / remove previous item. Links in deque invalid if you add / remove from the middle.

Otherwise, references and iterators are safe to preserve the life cycle of the base object.

+11
source

If the vector changes, the content will be effectively recreated by copying and / or assignment. The new contained objects will (probably) be in different places, and therefore any pointers to them or their members will be (probably) invalid - you should, of course, assume that this is so.

+1
source

Yes, your instincts are true. If the standard mentions that an iterator is invalid, it also tends to indicate that links are also invalid.

For example, here is some partial text describing some of the effects of a vector function-reservist:

  Notes: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. 

I cannot imagine any member functions of any container that would deprive the iterator of specific elements, but not pointers or references to the same elements, but I believe that I could be wrong.

It's best to check what the standard says for your specific container and member function.

+1
source

Your assumption is reasonable for a vector, because an iterator can be implemented as a thin wrapper around a pointer. As an alternative to pointers, you can save offsets to a vector. They would be nullified by insertion and erasure, but not by reallocation of memory.

0
source

Source: https://habr.com/ru/post/1305848/


All Articles