According to the draft standard (23.3.6.4 vector data), data() points to the underlying array and [data(), data() + size())
must be a valid range:
T* data() noexcept;
const T* data() const noexcept;
1 Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector,
data() == &front().
2 Complexity: Constant time
But what if the vector is empty? When I construct a zero-size vector:
#include <vector>
#include <iostream>
int main() {
const int NUM = 0*10;
std::vector< double > v( NUM, 0.0 );
std::cerr << "V : "<< v.data() << std::endl;
}
MSVC 2010 returns null, but on Linux (with GCC 4.2.1 and Intel 12.1) I get a non-null address.
Is vector::data()
allowed to or should it return null? Could an implementation, for example, do a default-size initial allocation and return a (non-null) pointer to it?
Edit: Several answers focus on the validity of an empty-range. I fully agree there.
I would really like to see a good reference or explanation for: Is it allowed to, must it return null or may it also return non-null?
std::vector::begin Returns an iterator pointing to the first element in the vector. Notice that, unlike member vector::front, which returns a reference to the first element, this function returns a random access iterator pointing to it. If the container is empty, the returned iterator value shall not be dereferenced.
C++ vector::empty() function vector::empty() is a library function of "vector" header, it is used to check whether a given vector is an empty vector or not, it returns a true if the vector size is 0, otherwise it returns false. Note: To use vector, include <vector> header. vector::empty();
The find() function returns an iterator that points to the val in the specified range. If the value is not found, then it returns an iterator to the last of the array or vector.
empty() returns true if the vector is empty, or false if the vector is not empty.
The convention for ranges is [inclusive, exclusive)
, that is if you iterate over a range [X,Y)
you will conceptually do the following (pseudo-code):
for( iterator ii = X; ii != Y; ++ii) {
...
}
This permits to express an empty range as [X,X)
. Also this empty range is perfectly well defined for each address, no matter if it is valid or invalid.
That said the requirements for data()
are (emphasis mine):
23.3.6.4 [vector.data]
T* data() noexcept;
const T* data() const noexcept;
Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector, data() == &front().
It seems to me that the only unconditional guarantee is that [data(),data() + size())
should be a valid range. For size() == 0
the member function data()
may return any value and the range will be a valid empty range. Therefore I would say that an implementation is allowed to return a non-null pointer if size()
is zero.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With