【问题标题】:Moving data from shared_ptr to vector constructor [duplicate]将数据从 shared_ptr 移动到向量构造函数[重复]
【发布时间】:2021-09-07 21:34:50
【问题描述】:

我有一个库,其中包含一个返回以下内容的函数:

std::shared_ptr<const uint8_t[]>
and
uint32_t size

我需要将它传递给另一个 API,该 API 需要:

std::vector<uint8_t> data

shared_ptr 中包含的数据与需要进入 vector 的数据完全相同,因此 move 操作是理想的.

所以我的问题是:有什么方法可以在不复制数据的情况下获得它?我意识到问题在于 shared_ptr 一旦超出范围就会删除数据,所以我想知道是否有办法绕过这个问题。

(如果需要复制,那么最有效的方法是什么?我在想 std::copy 或 good'ol' memcpy。)

【问题讨论】:

  • 也许你的意思是shared_ptr&lt;const uint8_t[]&gt;
  • @AyxanHaqverdili 这是一个指向字节数组开头的指针。
  • fwiw,从对象中删除移动完全没问题。你试图规避的不是问题
  • 最好的复制方式是vector&lt;uint8_T&gt; data( ptr.get(), ptr.get() + size )

标签: c++ vector std shared-ptr


【解决方案1】:

不,向量不可能拥有单独分配的数组的所有权。

如果您需要矢量,而源不是矢量,则必须复制(您可以移动单个元素,但这与复制 std::uint8_t 的情况相同)。

如果您希望避免复制,则必须更改其中一个前提:以向量开头(如果库允许),或者不创建向量。

我在想 std::copy 或 good'ol' memcpy。

使用std::memcpy 而不是std::copy 的唯一原因是重新解释数据(std::copy 也可以用于此,但语法因必要的强制转换而变得笨拙),而您没有这样做在这里。

std::copy 和接受一对迭代器的向量构造函数一样好。

我意识到问题在于 shared_ptr 一旦超出范围就会删除数据,所以我想知道是否有办法规避这个问题。

您的直觉是正确的,为了实现您想要的,必须将指针从共享指针的所有权中释放出来。但是,这还不够,因为您不能让 vector 取得该所有权。

但是关于是否有办法防止共享指针删除拥有的指针:是的,可以通过编写自定义删除器类来实现。但是创建共享指针的库必须让您控制删除器,我怀疑情况并非如此。

这也将非常危险,因为您必须确保拥有指针所有权的任何东西都必须使其保持活动状态,至少只要指向“已发布”数据的最长存活共享指针......除非您控制所有共享所有者,否则非常困难。

【讨论】:

  • shared_ptr 也无法释放所有权。 unique_ptr 可以。
  • @AyxanHaqverdili shared_ptr 不能,但自定义删除器可以,正如我在答案中描述的那样。虽然,有一些严重的警告。
猜你喜欢
  • 2013-12-13
  • 2017-06-11
  • 2023-03-20
  • 2016-06-20
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多