Reputation: 3438
If I have a C type raw pointer, is it possible to create a std::vector
from the same type that owns the pointer's data without any data copy (only moving)? What motivates me for asking this question is the existence of data()
member function for std::vector
which means vector's elements are residing somewhere in the memory consecutively.
Edit: I have to add that the hope I had was also intensified by the existence of functions like std::make_shared
.
Upvotes: 4
Views: 924
Reputation: 25439
I don't think that this is directly possible, although you're not the first one to miss this feature. It is even more painful with std::string
which doesn't have a non-const
data
member. Hopefully, this will change in C++17.
If you are allocating the buffer yourself, there is a solution, though. Just use a std::vector
up-front. For example, assume you have the following C-style function,
extern void
fill_in_the_numbers(double * buffer, std::size_t count);
then you can do the following.
std::vector<double>
get_the_numbers_1st(const std::size_t n)
{
auto numbers = std::vector<double> (n);
fill_in_the_numbers(numbers.data(), numbers.size());
return numbers;
}
Alternatively, if you're not so lucky and your C-style function insists in allocating the memory itself,
extern double *
allocate_the_buffer_and_fill_in_the_numbers(std::size_t n);
you could resort to a std::unique_ptr
, which is sadly inferior.
std::unique_ptr<double[], void (*)(void *)>
get_the_numbers_2nd(const std::size_t n)
{
return {
allocate_the_buffer_and_fill_in_the_numbers(n),
&std::free
};
}
Upvotes: 3
Reputation: 21576
Yes, provided that you've created and populated the vector before getting the pointers and that you will not
vec.size() == vec.capacity() - 1
,,, doing so will change the address of the elements Example
#include <iostream>
void fill_my_vector<std::vector<double>& vec){
for(int i=0; i<300; i++){
vec.push_back(i);
}
}
void do_something(double* d, int size)
{ /* ..... */ }
int main(){
std::vector<double> vec;
fill_my_vector(vec);
//You hereby promise to follow the contract conditions, then you are safe doing this
double* ptr;
int ptr_len = vec.size();
ptr = &vec[0];
//call do_something
do_something(ptr, ptr_len);
//ptr will be alive until this function scope exits
}
If you mean managing the data from an already created array, you can't... vector manages its own array... It cannot take ownership of an array that wasn't created by its class (vector).
Upvotes: 0
Reputation: 60367
No, std::vector
is not designed to be able to assume/utilize a pre-existing array for its internal storage.
Upvotes: 2