【问题标题】:How can I change the pointer in shared_ptr without losing the ability to delete the memory?如何更改 shared_ptr 中的指针而不失去删除内存的能力?
【发布时间】:2021-09-22 15:05:54
【问题描述】:

我遇到了std::shared_ptr 的问题。我有一个代码:

void Receive(const std::shared_ptr<char[]>& data, uint32_t length) {
  this->next->Receive(data + 2, length - 2);
}

我需要将 shared_ptr 增加 2 而不会失去删除内存的能力。

我不想复制数据,因为数据已经在内存中并且我拥有这些数据。如果我可以更改指针而不损失性能,那么复制数据只是为了替换和删除旧数据是愚蠢的。 shared_ptr 是否可以包含并返回一个指针,但删除另一个?

据我所知,shared_ptr 的内部包含指向由get() 函数返回的数据的指针,并包含对控制块的引用,该控制块对引用进行计数,并且应该在所有引用消失后删除内存.

所以,由于它包含与控制块分开的指针,也许我可以在不改变指向控制块中分配的内存块的指针的情况下以某种方式更改它,而不会失去删除内存的能力?如果我不能,也许我可以用boost::shared_ptr 来做?

我还没有检查。我不使用 Boost 库,但如果它对我有帮助,我会使用。

【问题讨论】:

  • 您可以改用void Receive(char* data, uint32_t length) 吗?甚至可以考虑void Receive(std::span&lt;char&gt; data);

标签: c++ memory boost shared-ptr


【解决方案1】:

是的,这就是 std::shared_ptr 的别名构造函数的用途。它保持相同的控制块,但它允许您使用另一个指针。

签名是

template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;

在你的情况下

void Receive(const std::shared_ptr<char[]>& data, uint32_t length) {
  std::shared_ptr<char[]> alias(data, data.get()+2);
  this->next->Receive(alias, length - 2);
}

但我确实质疑在这种情况下使用shared_ptr。在这种情况下,您真的拥有共享所有权吗?你不能找出可以拥有这个内存的代码的一部分吗?

【讨论】:

  • 我很想将偏移量、长度和共享 ptr 加入到自己的结构中。实现 + 和 ++ 以及剩余长度等。也是一元星和 arriw 解引用。开销适中,调试更友好。加上 ptr 和 length 是一个包,而不是两个参数,
  • @Yakk-AdamNevraumont 可能是另一个用例。但是指定的功能会更好地使用char* 并让呼叫站点执行sptr.get() 呼叫。因为它传递了const std::shared_ptr&lt;T&gt;&amp;,所以通过引用来获取它,甚至不参与所有权。在这种情况下(如所示),使用 shared_ptr 没有任何好处
  • 我的意思是,理论上,对next-&gt;Recieve 的调用可以中断读取并从传入的共享ptr 中获取所有权,并立即返回,例如。
猜你喜欢
  • 2019-03-31
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 2015-11-27
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
相关资源
最近更新 更多