Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it legal to have a pointer to a reserved vector element? [duplicate]

I'm curious if this sort of thing is legal:

std::vector<some_class_type> vec;
vec.reserve(10);
some_class_type* ptr = vec.data() + 3; // that object doesn't exist yet

Note that I'm not attempting to access the value pointed to.

This is what the standard says about data(), but I'm not sure if it's relevant:

Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector, data() == &front().

like image 902
Pubby Avatar asked Dec 20 '14 15:12

Pubby


People also ask

Can vectors hold pointers?

You can store pointers in a vector just like you would anything else. Declare a vector of pointers like this: vector<MyClass*> vec; The important thing to remember is that a vector stores values without regard for what those values represent.

Does vector erase delete pointers?

Yes. vector::erase destroys the removed object, which involves calling its destructor.

How do you assign a pointer to a vector?

To assign a pointer to 'point to' an instance of an object use pointer = &vector_of_reviews . The & operator gets the address of something, and it's this that you want to assign to the pointer. *pointer = vector_of_reviews dereferences the pointer (obtains the actual object 'pointed to').

Does vector Reserve allocate memory?

vector::reserve does allocate memory, so your question about reserving memory without allocating is incorrect. The point is that reserving memory can be done without changing the vectors size. Basically a vector has two sizes, it's size and it's capacity.


1 Answers

  1. data must return a pointer to a valid range ([vector.data]). Pointers that point into that range, including the one that points one past the last element of the range, must be stable until next reallocation. When size() is zero, data() points past the end of an empty range, which is a perfectly valid pointer to keep (but not to dereference of course).
  2. Since data must remain stable for the next 10 insertions, we can assume that a storage region suitably sized and aligned for placing an array of 10 elements in it was obtained, and data points to the beginning of that region. That is, the implementation must call an allocation function and set the internal data pointer to its return value. (There is no direct indication in the standard that this must be true, but I cannot imagine a situation where it might be false. I assume that reallocation mandated ([vector.capacity]) by the standard actually calls one of the allocation functions such as ::operator new or std::malloc, otherwise calling this operation "reallocation" would be rather dubious. At any rate, there seems to be no way to avoid such allocation on any current architecture).
  3. Any such storage region actually contains a live array of an appropriate size ([intro.object]) (though not necessarily live array elements, depending on the element type). Pointer arithmetic within such an array is valid, even though dereferencing resulting pointers is not necessarily valid.
like image 114
n. 1.8e9-where's-my-share m. Avatar answered Sep 17 '22 13:09

n. 1.8e9-where's-my-share m.