指针是否可能在没有任何数据副本的情况下被向量所拥有

Is it possible that a pointer gets owned by a vector without any data copy?

本文关键字:情况下 副本 向量 拥有 数据 任何 是否 指针      更新时间:2023-10-16

如果我有一个C类型的原始指针,是否可以从拥有指针数据的同一类型创建一个std::vector,而不需要任何数据副本(仅移动)?促使我提出这个问题的是std::vectordata()成员函数的存在性,这意味着向量的元素连续地存在于内存中的某个地方。

编辑:我必须补充一点,像std::make_shared这样的功能的存在也增强了我的希望。

我不认为这是直接可能的,尽管你不是第一个错过这个功能的人。没有非const data成员的std::string更令人痛苦。希望这种情况在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
  };
}

否,std::vector的设计不能假定/利用预先存在的阵列作为其内部存储。

是的,前提是您在获取指针之前已经创建并填充了向量,并且您不会

  1. 擦除任何元素
  2. vec.size() == vec.capacity() - 1、、时,将不会添加新元素,这样做更改元素的地址

示例

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

编辑

如果您的意思是管理已经创建的阵列中的数据,则不能。。。vector管理自己的数组。。。它不能拥有不是由其类(向量)创建的数组的所有权。

相关文章: