TruLa
TruLa

Reputation: 1147

C++ access vector beyond size() and under capacity()

Is it safe to access vector's data()[i] for indices i beyond vector's size() and under vector's capacity()?

Here is my reasoning:

a) According the cplusplus, capacity() is "the size of the storage space currently allocated for the vector" which makes me think that the answer to my question is YES, but then

b) Using reserve() and access data beyond vector's size() should be safe because according to cplusplus, reserve() "causes the container to reallocate its storage increasing its capacity to n", but then

c) Stackoverflow topic contradicts the statement b) above

So I'm puzzled and looking for the answer.

Upvotes: 4

Views: 1778

Answers (2)

NathanOliver
NathanOliver

Reputation: 180585

It isn't valid to access data()[n] if n >= size(). Per [vector.data] std::vector::data

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

So it is only valid to access data with a value in the range of [0, size()).


Generally then memory between data() + size() - 1 and data + capacity() is uninitialized. If you read from that uninitialized memory that is undefined behavior. If you have an object that has non trivial initialization then you can't even assign a value to it since there isn't an object actually in that spot, just the space for one. You could probably get away with doing things in the uninitialized range, but your violating the contract with std::vector and it might get angry if you do ;)

Upvotes: 8

Superlokkus
Superlokkus

Reputation: 5039

No it is not safe because §23.3.6.4 of ISO/IEC 14882:2014 states

vector data ... Returns: A pointer such that [data(),data() + size()) is a valid range.

So by the standard everything beyond size() is not defined, meaning the so called undefined behaviour, which as everybody will confirm, is something very unsafe.

To be fair, usually nothing bad would happen, but this is a very weak usually, which means, another compiler, operating system, and boom things happen, and you can not tell that. And to be also complete, there are several implementations where this will crash, I think for example when you compile with address sanitisation. Just don't do it.

Upvotes: 3

Related Questions