views:

196

answers:

3

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 specialized vector in any way).

+8  A: 

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.

James McNellis
In 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.
PeterK
The 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?
JAB
@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.
James McNellis
@James: Don't worry, it's just me forgetting C++'s casting rules.
JAB
@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 ;)
PeterK
sellibitze
+12  A: 

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.

Job
While this is true, cplusplus.com is not a definitive reference.
Billy ONeal
@Billy ONeal: You're right, I edited my answer to give a better quote.
Job
It's not safe if the vector is empty, since `v[0]` or `v.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.
AshleysBrain
@AshleysBrain: Can you point to the section in the standard describing that `v[0]` when `v.empty()` is UB?
Job
JonM
Yes, @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.
Rob Kennedy
+4  A: 
daramarak