指针是否可能由向量拥有而没有任何数据副本?

时间:2016-04-01 17:51:56

标签: c++ c++11 vector move

如果我有一个C类型的原始指针,是否可以从拥有指针数据的相同类型创建std::vector而不进行任何数据复制(仅移动)?提出这个问题的动机是data() std::vector成员函数的存在,这意味着向量的元素连续存在于内存中的某个位置。

编辑:我必须补充一点,std::make_shared等函数的存在也强化了我的希望。

3 个答案:

答案 0 :(得分:3)

我不认为这是直接可能的,尽管你不是第一个错过这个功能的人。如果std::string没有非const data成员,则会更加痛苦。希望这会在C ++ 17中发生变化。

如果您自己分配缓冲区,则有一个解决方案。只需使用std::vector预先。例如,假设您具有以下C样式函数,

extern void
fill_in_the_numbers(double * buffer, std::size_t count);

然后您可以执行以下操作。

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

或者,如果你没那么幸运,你的C风格功能坚持分配内存本身,

extern double *
allocate_the_buffer_and_fill_in_the_numbers(std::size_t n);

你可以求助于std::unique_ptr,这是可悲的劣等。

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

答案 1 :(得分:2)

不,std::vector的设计不能为其内部存储假设/利用预先存在的数组。

答案 2 :(得分:0)

是的,只要您在获取指针之前创建并填充该向量,并且您不会

  1. 删除任何元素
  2. 您不会在vec.size() == vec.capacity() - 1时添加新元素,这样做更改元素的地址
  3. 实施例

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

    修改

    如果您的意思是管理已经创建的数组中的数据,那么您无法...矢量管理自己的数组......它不能取得其类没有创建的数组的所有权(矢量)。