Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ - pointer array to Vector?

Tags:

c++

double * values; // instead of this, std::vector<double> values; // I want this. 

An API I'm using provides a result as double* pointer. I want to wrap this with the std::vector<double> type.

like image 555
webnoon Avatar asked Sep 02 '11 01:09

webnoon


People also ask

How do I turn an array into a vector?

To convert an array to vector, you can use the constructor of Vector, or use a looping statement to add each element of array to vector using push_back() function.

How do you assign a pointer to a vector in C++?

To assign a pointer to 'point to' an instance of an object use pointer = &vector_of_reviews . The & operator gets the address of something, and it's this that you want to assign to the pointer. *pointer = vector_of_reviews dereferences the pointer (obtains the actual object 'pointed to').

Is vector name a pointer?

std::vector is a sequence container that encapsulates dynamic size arrays. So definately, it is not a pointer.


2 Answers

You can't wrap an array in a vector in place and expect the vector to operate on that array. The best you can do is give the vector the double* and the number of values, which will have the vector make a copy of every element and put it in itself:

int arrlen = 0;  // pretending my_api takes arrlen by reference and sets it to the length of the array double* dbl_ptr = my_api(arrlen);   vector<double> values(dbl_ptr, dbl_ptr + arrlen);  // note that values is *not* using the same memory as dbl_ptr // so although values[0] == dbl_ptr[0], &values[0] != &dbl_ptr[0] 

And also, like Praetorian said, if the API you are using expects you to free the memory after using it, you might be interested in smart pointers. See Praetorian's answer.

like image 57
Seth Carnegie Avatar answered Oct 12 '22 11:10

Seth Carnegie


Others have suggested that you cannot wrap an array in a vector, but that's simply not true; think about it, a vector has an array as it's underlying data container! I had been attempting this off and on for quite some time before I came up with a workable solution. The caveat is that you have got to zero out the pointers after use in order to avoid double-freeing the memory.

#include <vector> #include <iostream>  template <class T> void wrapArrayInVector( T *sourceArray, size_t arraySize, std::vector<T, std::allocator<T> > &targetVector ) {   typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *vectorPtr =     (typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *)((void *) &targetVector);   vectorPtr->_M_start = sourceArray;   vectorPtr->_M_finish = vectorPtr->_M_end_of_storage = vectorPtr->_M_start + arraySize; }  template <class T> void releaseVectorWrapper( std::vector<T, std::allocator<T> > &targetVector ) {   typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *vectorPtr =         (typename std::_Vector_base<T, std::allocator<T> >::_Vector_impl *)((void *) &targetVector);   vectorPtr->_M_start = vectorPtr->_M_finish = vectorPtr->_M_end_of_storage = NULL; }  int main() {    int tests[6] = { 1, 2, 3, 6, 5, 4 };   std::vector<int> targetVector;   wrapArrayInVector( tests, 6, targetVector);    std::cout << std::hex << &tests[0] << ": " << std::dec             << tests[1] << " " << tests[3] << " " << tests[5] << std::endl;    std::cout << std::hex << &targetVector[0] << ": " << std::dec             << targetVector[1] << " " << targetVector[3] << " " << targetVector[5] << std::endl;    releaseVectorWrapper( targetVector ); } 

Alternatively you could just make a class that inherits from vector and nulls out the pointers upon destruction:

template <class T> class vectorWrapper : public std::vector<T> {    public:   vectorWrapper() {     this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;   }       vectorWrapper(T* sourceArray, int arraySize)   {        this->_M_impl _M_start = sourceArray;     this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;   }       ~vectorWrapper() {     this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;   }       void wrapArray(T* sourceArray, int arraySize)   {        this->_M_impl _M_start = sourceArray;     this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;   }    };   
like image 38
Ethereal Avatar answered Oct 12 '22 13:10

Ethereal