Is it safe to assume that STL vector storage is always contiguous?

Viewed 12113

If you have an STL vector which has been resized, is it safe to take the address of element 0 and assume the rest of the vector will follow in memory?

e.g.

vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
6 Answers

Yes, that is a valid assumption (*).

From the C++03 standard (23.2.4.1):

The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

(*) ... but watch out for the array being reallocated (invalidating any pointers and iterators) after adding elements to it.

The C++03 standard added wording to make it clear that vector elements must be contiguous.

C++03 23.2.4 Paragraph 1 contains the following language which is not in the C++98 standard document:

The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

Herb Sutter talks about this change in one of his blog entries, Cringe not: Vectors are guaranteed to be contiguous:

... contiguity is in fact part of the vector abstraction. It’s so important, in fact, that when it was discovered that the C++98 standard didn’t completely guarantee contiguity, the C++03 standard was amended to explicitly add the guarantee.

Storage is always contiguous, but it may move as the vector's capacity is changed.

If you had a pointer, reference, or iterator on element zero (or any element) before a capacity-changing operation, it is invalidated and must be reassigned.

std::vector guarantees that the items are stored in a contiguous array, and is therefore the preferred replacement of arrays and can also be used to interface with platform-dependent low-level code (like Win32 API calls). To get a pointer to the array use:

&myVector.front();
Related