2011-09-02 60 views
19
double * values; // instead of this, 
std::vector<double> values; // I want this. 

API tôi đang sử dụng cung cấp kết quả là con trỏ double*. Tôi muốn bọc nó với loại std::vector<double>.C++ - mảng con trỏ tới Vector?

+1

Hãy nhớ rằng bạn có thể nhận được 'std :: vector' để sao chép các yếu tố trở về từ mảng như được hiển thị bên dưới, nhưng nếu API này yêu cầu bạn gọi một hàm khác để giải phóng bộ nhớ được cấp phát cho mảng đó hoặc tự xóa mảng, bạn phải làm điều đó. Tạo vectơ sẽ không giải phóng bộ nhớ đó. – Praetorian

+0

Chức năng API của bạn * trả về * một 'double *', hay nó lấy một con trỏ làm đối số * và điền nó với dữ liệu? –

+0

Kerrek SB // điểm tốt! một cái gì đó trả về một đôi * cái gì đó lấy một con trỏ làm đối số. – webnoon

Trả lời

23

Bạn không thể quấn mảng trong một vector tại chỗ và mong đợi vectơ hoạt động trên mảng đó. Điều tốt nhất bạn có thể làm là cung cấp cho các vector các double* và số lượng các giá trị, trong đó sẽ có vector tạo một bản sao của tất cả các yếu tố và đặt nó trong chính nó:

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] 

Và cũng như thuộc về pháp quan nói rằng, nếu các API bạn đang sử dụng dự kiến ​​bạn sẽ giải phóng bộ nhớ sau khi sử dụng nó, bạn có thể quan tâm đến con trỏ thông minh. Xem Praetorian's answer.

+3

Câu hỏi đơn giản có thể là câu trả lời phức tạp: TẠI SAO không có cách nào để bao bọc một vector STL xung quanh hiện tại mảng đồng bằng (tại chỗ)? Có phải vì STL giả định rằng kích thước dành riêng là sức mạnh của 2? Nếu không, tôi không thấy lý do tại sao tại sao điều này không thể thực hiện được ... –

+2

@JakobS. bởi vì vector khăng khăng kiểm soát việc cấp phát và phân bổ lại bộ nhớ của nó.Các đảm bảo được thực hiện bởi các hàm thành viên không thể giữ được nếu vectơ không thể điều khiển mảng bên dưới. –

4
const int N = 10; // Number of elements in your array 
std::vector<double> vec_values(values, values + N); 

Điều này sẽ sao chép dữ liệu trong values thành std::vector.

+1

'values' là' double * ', không phải là' double [] ', do đó' sizeof (values) == sizeof (double *) ', không phải là số phần tử trong mảng. Bạn cần 'std :: vector vec_values ​​(giá trị, giá trị + numValues)' – Praetorian

+0

@Praetorian: Xin lỗi, quên thực hiện thay đổi – Jacob

1

Sử dụng vector constructor iterator

std::vector<int> value_vec (value, value + n); //suppose value has n elements

5

Những câu trả lời khác cho thấy làm thế nào để tạo một bản sao của mảng trở lại và tạo ra một vector, nhưng giả sử các API cấp phát bộ nhớ cho mảng và hy vọng người gọi để xóa nó, bạn cũng có thể muốn xem xét gắn bó mảng vào một con trỏ thông minh và sử dụng nó như là.

int numValues; 
std::unique_ptr<double[]> values(apiFunction(&numValues)); 

Bạn vẫn có thể sao chép số này thành vector nhưng nếu bạn thực hiện các bước trên, bạn không phải lo lắng về việc xóa mảng đã trả về.

6

Đây có lẽ là câu trả lời bạn đang tìm kiếm. Những người khác đã gợi ý rằng bạn không thể quấn một mảng trong một vec-tơ, nhưng điều đó đơn giản là không đúng; suy nghĩ về nó, một vectơ có một mảng vì nó là vùng chứa dữ liệu cơ bản! Tôi đã cố gắng này và trong một thời gian khá lâu trước khi tôi đưa ra một giải pháp khả thi. Thông báo trước là bạn phải loại bỏ con trỏ sau khi sử dụng để tránh việc giải phóng bộ nhớ.

#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); 
} 

Hoặc bạn chỉ có thể làm cho một lớp kế thừa từ vector và null ra các con trỏ khi tiêu hủy:

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; 
    } 
}; 
Các vấn đề liên quan