【问题标题】:std::shared_ptr with aliasing constructor, is it possible the retrieve the initial pointer value?std::shared_ptr 带有别名构造函数,是否可以检索初始指针值?
【发布时间】:2019-12-16 10:52:46
【问题描述】:

这个c++17代码使用shared_ptr的(8) aliasing constructor

#include <iostream>
#include <memory>

using namespace std;

int main()
{
  auto shared_1 = std::shared_ptr<int[]>(new int[10], std::default_delete<int[]>());

  int* p_data = shared_1.get(); 

  auto shared_2 = std::shared_ptr<int[]>(shared_1, p_data + 5); // aliasing constructor

  std::cout << std::hex << p_data << "\t" << shared_1.get() << std::endl;

  std::cout << std::hex << p_data + 5 << "\t" << shared_2.get() << std::endl; // Is it possible 
                                                                              // to retrieve the
                                                                              // initial p_data value?
}

并打印:

0x556f38865e70    0x556f38865e70
0x556f38865e84    0x556f38865e84

问题: 假设我只存储shared_2(而不是shared_1,也不是+5 偏移量),这个p_data 初始值(存储在shared_1)是否丢失或者是否仍然可以从@987654329 中检索它仅限@?

【问题讨论】:

  • 如果你只有shared_2,那么它的指针就是你所拥有的。无法知道它是如何构建的或它可能指向什么样的数据。如果您需要获取“原始”指针,您需要自己跟踪它。
  • ^^ 是的,两个 shared_pointer 之间唯一共享的是控制块,它不暴露给公共 API。
  • @Someprogrammerdude 谢谢,这是我的问题。在引入额外的存储空间来存储偏移量之前,我想确定一下。您可以将您的评论变成答案,我很乐意为它投票。
  • @Someprogrammerdude shared_ptr 的别名构造函数从一开始就存在。在 c++20 中为它添加了另一个(右值)重载。此代码使用较早的构造函数。标签不应更改。
  • @Someprogrammerdude - 不是。它只是重载了 shared_ptr 右值,这里没有使用。自 C++11 以来就有一个别名 c'tor,它通过 const 引用获取。

标签: c++ c++17 shared-ptr


【解决方案1】:

您无法单独从shared_2 检索p_data

shared_2 中存储的值不需要与原始指针有任何关系,并且无法检索用于初始shared_ptr 的“原始”值,其中别名指针都共享相同的管理块。

您可以使用自定义删除器,并在创建shared_ptr 时将数据存储在删除器中,然后使用get_deleter 检索删除器,从而从中检索数据。

【讨论】:

  • shared_ptr不是将“原始”指针存储在控制块中,以便能够销毁完整的“原始”对象吗?
  • 是的,确实如此,但您无法通过公共 API 取回它。
  • @MaximEgorushkin 它可能以不透明的形式存储,无法通过控制块的接口访问(接口暴露于shared_ptrweak_ptr)。
猜你喜欢
  • 2015-08-28
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多