指针是不是有可能在没有任何数据副本的情况下由向量拥有?
Posted
技术标签:
【中文标题】指针是不是有可能在没有任何数据副本的情况下由向量拥有?【英文标题】:Is it possible that a pointer gets owned by a vector without any data copy?指针是否有可能在没有任何数据副本的情况下由向量拥有? 【发布时间】:2016-04-01 17:51:55 【问题描述】:如果我有一个 C 类型的原始指针,是否可以从拥有指针数据的同一类型创建一个 std::vector
而无需任何数据复制(仅移动)?我提出这个问题的动机是data()
的成员函数std::vector
的存在,这意味着向量的元素连续驻留在内存中的某个位置。
编辑:我必须补充一点,std::make_shared
等功能的存在也增强了我的希望。
【问题讨论】:
是的,但担心矢量被调整大小并使您的指针无效。如果向量永远不会改变大小并且你可以保证这一点,那么你是安全的。 你在分配缓冲区吗?然后你可以让向量来代替。否则,我不知道如何实现。 @user4581301 您可以将现有数组的所有权转移到向量吗?这对我来说是个新闻 每当您创建一个 vector 时,它都拥有它所包含的对象。data()
返回的 pointer 是指向 vector 拥有的数据的非拥有原始指针。
@5gon12eder 我确实分配了缓冲区,但我仅限于使用 C 级 API 来执行此操作。
【参考方案1】:
我认为这不是直接可能的,尽管您不是第一个错过此功能的人。没有非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
;
【讨论】:
【参考方案2】:不,std::vector
并非设计为能够假定/利用预先存在的阵列作为其内部存储。
【讨论】:
【参考方案3】:是的,前提是您在获取指针之前创建并填充向量并且您不会
-
擦除任何元素
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 管理它自己的数组……它不能取得不是由它的类(vector)创建的数组的所有权。
【讨论】:
如果是,现在我的问题是如何? 好的,让我修改我对“如何”的回答 朋友,我们似乎都误读了这个问题。 @Farzad 似乎有一个预先分配的内存池,他希望使用向量来管理,而不是将向量用作内存池。 编辑部分就是我的意思。以上是关于指针是不是有可能在没有任何数据副本的情况下由向量拥有?的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 中,是不是可以针对这些对象的任何属性轻松地对对象类型指针的向量进行排序?