Is it safe to pass a vector as an array?
Solution 1
From section 23.2.4, point 1 of the standard:
[...] 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().
So yes, it is safe.
Note: If v
is empty v[0]
is undefined behavior so you should only do this if v
is not empty.
Solution 2
As others has suggested it is safe.
But I would like to have a small reservation. If this function accept an array and stores it for later use you might have a problem. This is because std::vector might freely deallocate its memory if it needs it to change size. So if this function just uses the array (makes a copy or whatever) or you never alter it, it is safe.
I just want to point that out, just because the vectors elements are stored contiguous it isn't automatically safe to pass around. Ownership is still an issue.
Solution 3
Yes. Assuming v.size() > 0
, this is safe (If the vector is empty, then v[0]
results in undefined behavior).
The elements of a std::vector
container are stored contiguously, just like in an ordinary array.
uj2
Updated on June 15, 2022Comments
-
uj2 about 2 years
Say I have a function:
void someFunc(int *x,int count);
which is out of my control, so I can't write it to accept iterators.
Is it safe to call it like so (regardless of the specific STL implementation):
vector<int> v; /* ... */ someFunc(&v[0],v.size());
Obviously, one counter example is
vector<bool>
. How about any other type? (assuming I haven't specializedvector
in any way). -
PeterK about 14 yearsIn this case, yes. Would it be safe even with a vector with pointers to a base class? (so at runtime, pointers to derived classes could be passed). Assuming that someFunc() will dereference those, of course.
-
JAB about 14 yearsThe value of a pointer is just an integer, so technically it would work, but you'd probably still get a warning or error for passing an array of pointers to classes rather than an array of integers unless you messed with casting. Or does C++ allow passing pointers as integers without explicit casting?
-
James McNellis about 14 years@PeterK: Yes; why do you think it wouldn't it work with pointer elements? @JAB: I really don't know what you are trying to say.
-
JAB about 14 years@James: Don't worry, it's just me forgetting C++'s casting rules.
-
Billy ONeal about 14 yearsWhile this is true, cplusplus.com is not a definitive reference.
-
PeterK about 14 years@James McNellis: Sorry, i was just confused. It would of course work. (What i had in mind was that derived classes may be bigger than their base classes (when it comes to memory)). This of course does not affect pointers ;)
-
mtvec about 14 years@Billy ONeal: You're right, I edited my answer to give a better quote.
-
AshleysBrain about 14 yearsIt's not safe if the vector is empty, since
v[0]
orv.front()
are undefined behavior that way. Since this is the top-voted and chosen answer, it would be good to include that. Also, if the function stores the pointer long-term and the vector is freed or reallocates, the pointer becomes invalid. -
sellibitze about 14 years@PeterK: In case you are trying to invoke a function
void fun(Derived**);
using pointers stored in avector<Base*> vec;
the answer is no.&vec[0]
is of typeBase**
and this is not the same asDerived**
or even convertible to it. You couldreinterpret_cast
it, but it's technically undefined behaviour and it will blow up in your face if you toy with multiple inheritence where a conversion fromDerived*
toBase*
may require a pointer adjustment. -
mtvec about 14 years@AshleysBrain: Can you point to the section in the standard describing that
v[0]
whenv.empty()
is UB? -
JonM about 14 yearsAccessing
v[0]
is undefined behavior, but is it UB to take the address:&v[0]
? If you pass in a size of 0 to any well written function, it won't touch the array. -
Rob Kennedy about 14 yearsYes, @Jon, it's still undefined. You're calling the
vector::operator[]
function on a vector that has no elements. That in and of itself is undefined. At the point you're taking the address of the result and deciding whether or not to dereference that pointer, you're already in undefined-behavior territory. Nothing you do or don't do afterward can bring you back.