Reputation: 43
I apologize that I am still very new with C++, so your patience is appreciated.
As part of an un-alterable constraint in my project, I must convert a Vector to an Array. In my searching for a solution I have repeatedly come across answers like this one.
As I understand, that solution gives you a pointer to the first element in the vector -- and since a vector is guaranteed to be contiguous in memory you can then set the array to point to that memory location (or something like that).
My question is, though, how exactly do I do that in C++? The answer seems to suggest it is trivial, but I can't find how to do it.
I have tried things of this nature but they don't work....
std::vector<double> v;
double* a = &v[0];
double myArray[100];
&myArray[0] = a;
Given a pointer to the first element in a sequence, how do I then use that pointer to 'populate' an array? Furthermore, do I have to worry about size differences/going out of bounds issues? Also, could I do this in reverse as well ('populate' a vector with a pointer to the first element of an array)?
Upvotes: 1
Views: 3100
Reputation: 310960
If you have a vector and an array as for example
std::vector<double> v;
double myArray[100];
and want that the array would contain elements of the vector you should copy elements of the vector in the array as for example
std::copy( v.begin(),
std::next( v.begin(), std::min<std::vector<double>::size_type>( v.size(), 100 ) ),
std::begin( myArray ) );
or
std::copy( v.begin(),
v.begin() + std::min<std::vector<double>::size_type>( v.size(), 100 ),
myArray );
If you want that the vector would have elements of the array then you can write
v.assign( std::begin( myArray ), std::end( myArray ) );
or
v.insert( v.end(), std::begin( myArray ), std::end( myArray ) );
Or you can declare the vector and initialize it at the same time (after defining and filling the array)
std::vector<double> v( std::begin( myArray ), std::end( myArray ) );
that is the same as
std::vector<double> v( myArray, myArray + 100 );
Upvotes: 1
Reputation: 141554
It is possible to make an array reference:
vector<double> v(100); // must size the vector first, or at least add 1 element and call reserve(100)
double (&myArray)[100] = reinterpret_cast<double(&)[100]>(v[0]);
Then you can use myArray[0]
, myArray[1]
etc. However if you insert into the vector then myArray
becomes invalid (and it is not possible to 'move' it).
Although this is possible it would be very unusual so you should not do it in any real code.
Upvotes: 0
Reputation:
It depends on the lifetime of the array and vector, as well as how you plan on using the array.
If you merely want to access the vector as an array, you can do it as simply as you have written:
double* myArray = &v[0];
Or, using C++11 or higher:
double* myArray = v.data();
Then you may access the vector as if it were an array using myArray
. Effectively, this just aliases the vector's internal memory to a separate pointer. The subscript operator []
works on pointers, thus allowing myArray to more or less function as an array.
However, there are two gotchas with this:
myArray
is fully encompassed by that of v
. If the vector goes out of scope, is cleared, or is resized, myArray
is invalidated. You are merely pointing to the internal memory of v
, so anything that changes that memory will break myArray
.v
has no size. Give it a size before taking its address.If you want to copy the contents of the vector to an array, you can use memcpy()
.
double* myArray = new double[v.size()];
memcpy( myArray, &v[0], v.size() * sizeof( double ) );
This will allocate the number of elements currently in v
in myArray
and populate that memory with the data contained in v
. However, any changes to myArray
will be independent of v
. You merely copied the vector into the array.
There are several other ways to accomplish the second option.
Upvotes: 0
Reputation: 119144
You cannot insert elements into a vector using a pointer to the vector's first element. A vector uniquely owns its contents, and therefore must allow you to change its size only using its own interface, otherwise it cannot keep track of how many elements it owns.
You can do this:
std::vector<double> v(N); // N elements initialized to 0.0
double* a = v.data();
do_something(a, N); // tell the function to write N elements
Upvotes: 5