Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-指向向量的指针数组? double*值;//而不是这个,, std::向量值;//我想要这个。_C++ - Fatal编程技术网

C++ C++;-指向向量的指针数组? double*值;//而不是这个,, std::向量值;//我想要这个。

C++ C++;-指向向量的指针数组? double*值;//而不是这个,, std::向量值;//我想要这个。,c++,C++,我使用的API提供了一个结果,即double*指针。我想用std::vector类型来包装它。const int N=10;//数组中的元素数 double * values; // instead of this, std::vector<double> values; // I want this. 标准::向量向量向量u值(值,值+N); 这将把值中的数据复制到标准::向量 不能将数组封装在向量中,而期望向量在该数组上运行。你能做的最好的事情就是给向量一个double*和值

我使用的API提供了一个结果,即
double*
指针。我想用std::vector类型来包装它。

const int N=10;//数组中的元素数
double * values; // instead of this,
std::vector<double> values; // I want this.
标准::向量向量向量u值(值,值+N);

这将把
中的数据复制到
标准::向量

不能将数组封装在向量中,而期望向量在该数组上运行。你能做的最好的事情就是给向量一个
double*
和值的数量,这将使向量复制每个元素并将其放入自身:

const int N = 10; // Number of elements in your array
std::vector<double> vec_values(values, values + N);
int arrlen=0;
//假装my_api通过引用获取arrlen并将其设置为数组的长度
double*dbl_ptr=my_api(arrlen);
向量值(dbl_ptr,dbl_ptr+arrlen);
//注意,值*不*使用与dbl_ptr相同的内存
//因此,尽管值[0]==dbl_ptr[0],&值[0]!=&dbl_ptr[0]

而且,正如Praetorian所说,如果您正在使用的API希望您在使用后释放内存,那么您可能会对智能指针感兴趣。请参阅。

使用向量迭代器构造函数


std::vector value\u vec(值,值+n)//假设值有n个元素< /代码> 

其他答案显示如何复制返回数组并创建一个<代码> vector <代码>,但是假设API为数组分配内存,并期望调用方删除它,您可能还想考虑将数组粘贴到智能指针中并使用它。
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]
int数值;
std::唯一的_ptr值(apiffunction(&numValues));

您仍然可以将其复制到
向量
,但如果您执行上述步骤,就不必担心删除返回的数组。

其他人建议您不能将数组包装到向量中,但这根本不是真的;想想看,向量有一个数组作为它的底层数据容器!在我想出一个可行的解决方案之前,我已经断断续续地尝试了很长一段时间。需要注意的是,您必须在使用指针后将其归零,以避免双重释放内存

int numValues;
std::unique_ptr<double[]> values( apiFunction( &numValues ) );
#包括
#包括
模板
void wrapArrayInVector(T*sourceArray,size\u T arraySize,std::vector和targetVector){
typename std::_Vector_base::_Vector_impl*vectorPtr=
(typename std::_Vector_base::_Vector_impl*)((void*)和targetVector);
vectorPtr->_M_start=sourceArray;
vectorPtr->\u M\u finish=vectorPtr->\u end\u of_storage=vectorPtr->\u M\u start+arraySize;
}
模板
无效释放向量包装器(std::vector和targetVector){
typename std::_Vector_base::_Vector_impl*vectorPtr=
(typename std::_Vector_base::_Vector_impl*)((void*)和targetVector);
vectorPtr->\u M_start=vectorPtr->\u M_finish=vectorPtr->\u M_end\u of_storage=NULL;
}
int main(){
int测试[6]={1,2,3,6,5,4};
std::vector targetVector;
wrapArrayInVector(测试,6,目标向量);

std::cout感谢@Ethereal提供了很好的解决方案,并使他/她的答案更加完整:

该代码不会在VisualC++中编译(可能会在GCC中),因为STD实现的不同,但有一些变化,它将完美地工作。

此代码在微软Visual C++(VS2015)中测试:

#包括
#包括
模板std::vector wrapArrayInVector(T*sourceArray,大小\u T arraySize){
std::vector targetVector;
std::vector::_Mybase*basePtr{(std::vector::_Mybase*)((void*)和targetVector)};
basePtr->_Get_data()。_Myfirst=sourceArray;
basePtr->\u Get\u data()。\u Mylast=basePtr->\u Get\u data()。\u Myend=basePtr->\u Get\u data()。\u Myfirst+arraySize;
返回目标向量;
}
int main(){
int*测试{new int[3]};
测试[0]=100;测试[1]=200;测试[2]=300;
std::vector targetVector{wrapArrayInVector(tests,3)};

std::cout如果使用C++11,可以使用
std::vector

#包括//标准::参考#
#包括
#包括

#include

请记住,您可以获取
std::vector
来复制从数组返回的元素,如下所示,但是如果此API希望您调用另一个函数来释放为数组分配的内存,或者您自己删除数组,则必须这样做。创建向量不会释放该内存。您的API函数是否返回
>double*
,还是将指针作为参数并用数据填充?Kerrek SB//这一点很好!有些东西返回double*,有些东西将指针作为参数。简单的问题可能会有复杂的答案:为什么没有办法将STL向量环绕现有的普通数组(就地)?是因为STL假设保留大小是2的幂吗?否则,我现在看不出有什么理由不可能…@JakobS。因为向量坚持控制其内存的分配和重新分配。如果向量不能控制底层arr,则成员函数所作的保证将无法成立嗯。
#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 );
}
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;
  }   
};  
#include <iostream>
#include <vector>

template<typename T> std::vector<T> wrapArrayInVector(T* sourceArray, size_t arraySize) {
    std::vector<T> targetVector;
    std::vector<T>::_Mybase* basePtr{ (std::vector<T>::_Mybase*)((void*)&targetVector) };
    basePtr->_Get_data()._Myfirst = sourceArray;
    basePtr->_Get_data()._Mylast = basePtr->_Get_data()._Myend = basePtr->_Get_data()._Myfirst + arraySize;
    return targetVector;
}

int main() {
    int* tests{ new int[3] };
    tests[0] = 100; tests[1] = 200; tests[2] = 300;
    std::vector<int> targetVector{ wrapArrayInVector(tests, 3) };
    std::cout << std::hex << &tests[0] << ": " << std::dec
    << tests[0] << " " << tests[1] << " " << tests[2] << std::endl;
    std::cout << std::hex << &targetVector[0] << ": " << std::dec
    << targetVector[0] << " " << targetVector[1] << " " << targetVector[2] << std::endl;
    std::cin.get();
}
int tests[3];
tests[0] = 100; tests[1] = 200; tests[2] = 300;
std::vector<int> targetVector = wrapArrayInVector(tests, 3);
Contents of the array: -4 -3 -2 -1 0 1 2 3 4 5 
Contents of the array, shuffled: 3 -4 -3 -1 1 0 5 2 4 -2 
Change values using the vector shuffled
Contents of the array: 43 44 51 45 47 46 49 42 50 48