Link to home
Start Free TrialLog in
Avatar of JLevick
JLevick

asked on

Convert vector<T> to T*

I need to pass the contents of an STL vector to a C function expecting an array. The way I am doing it is roughly as follows:

void func(int *a, int size) { ... }

vector<int> v;
...
func(v.begin().base(), v.size());

My question is, is this the standard way of doing this, ie do/should all implementations of iterator have a base() method returning a pointer? If not is there a more standard way? Despite my thinking that this would be a very common requirement I haven't seen anything on the web or in my books in terms of solutions, and for some reason vector doesn't seem to have the equivalent of string's c_str() method which basically does the same thing.
ASKER CERTIFIED SOLUTION
Avatar of GaryFx
GaryFx

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Axter
I agree with GaryFx, in that you should use &v[0] method.

If you want to use the begin() function method, then you should use it without adding .base() to it.
Example:
func(v.begin(), v.size());
Avatar of ivec
ivec

Here are 3 ways to get a pointer to the first item of an std::vector:
 T* p = &*v.begin();
 T* p = &v[0];
 T* p = &v.front();
In the first option, many will find the &* cryptic.
The second option is perfectly ok, but I dislike the kind of redundant use of the zero index.
The third option is my preferred one.

Unfortunately, it is ILLEGAL to use ANY of these three expressions if the container is empty. It might work as you expect, but formally it leads to undefined behavior (i.e. "it could be erasing your hard disk").
So you must check v.empty() before attempting to get a pointer to the vector's first element.
Woops, regarding the original question:
In the C++ standard, only reverse iterators have a "base()" member function, which returns the corresponding forward-iterator (caveat: dereferencing this iterator does not return the same item).
There is no such thing as a base() member in std::vector::iterator in standard C++.
>>The third option is my preferred one.

FYI:
Any C++ STL book that referrs to this convertion, always shows the "&v[0]" method as the correct and prefered method to use.

>>T* p = &*v.begin();
This is redundant.  All you need is the v.begin().
Example:
T* p = v.begin();

Out of the methods posted, &v.front() would be the least preferred method.


Avatar of JLevick

ASKER

The version of the STL I'm using (default with VS .NET) base() does return a pointer for both forward and reverse iterators and without using it (ie just v.begin()) the compiler complains that it can't convert between an iterator and a pointer. So it seems &v[0] is the best solution, thanks.