Вопрос

Suppose I have the following:

struct Foo {
Foo () : bar(NULL), box(true) {}
Bar* bar;
bool box;
};

and I declare the following:

std::vector<Foo> vec(3);

I have a function right now which does something like this:

Foo& giveFoo() { //finds a certain foo and does return vec[i]; }

Then the caller passes along the address of the Foo it obtains by reference as a Foo* to some other guy. What I'm wondering, however, is if this pointer to Foo will remain valid after a vector grow is triggered in vec? If the existing Foo elements in vec are copied over then presumably the Foo* that was floating around will now be dangling? Is this the case or not? I'm debugging an application but cannot reproduce this.

Это было полезно?

Решение

Any pointers or references to elements will be invalidated when the vector is reallocated, just like any iterators are.

Другие советы

The pointer will remain valid until you call a non-const member function on the vector that:

  • causes its size to grow beyond its capacity (when that happens, the internal storage will be reallocated and all pointers and references to the elements will be invalidated) or

  • inserts an element before the element that the pointer points to, or

  • deletes the element from the vector, or

  • deletes an element from the vector that was located before the element that the pointer points to.

The first two bullets can happen at the same time. The difference is that references/pointers to elements located before insertion point remain valid as long as the size doesn't exceed capacity.

Yes it may become invalid because basically when vector needs to increase it's reserved size, it just deletes it's internal storage (which is basically an array), allocates enlarged one and copies it's previous contents there.

If you sure that index stays the same though you may access desired data by using this index each time you need it.

Below is what the standard says about the validity of vector iterators for vector modifiers:

vector::push_back(), vector::insert(), vector::emplace_back(), vector::emplace():

Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid.

vector::erase():

Invalidates iterators and references at or after the point of the erase.

Any assumption beyond that is not safe.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top