将new_pointer设置为old_pointer + offset的shared_ptr

时间:2019-02-17 20:49:16

标签: c++ shared-ptr smart-pointers pointer-arithmetic

这是一个智能指针:std::shared_ptr<char> p(new char[size]),它代表填充有原始二进制文件内容的数组。在整个数组从文件复制到RAM之后(也只有在此之后),我可以对其进行解析,在此期间,我会检索一些头信息(一些第一个双字)。然后是实际数据

在不提供更多上下文的情况下,对于将提到的共享指针设置为以实际数据开头的新地址来说,这很方便。该地址仍在分配的内存中。但是如何设置而不丢失它呢?

一个问题是(是/否):是否可以将p设置为上一个指针的偏移量而不调用数据删除?

1 个答案:

答案 0 :(得分:41)

是的,这是可能的。您可以使用构造函数8,此引用中的别名构造函数https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

// make sure you use an array deleter
std::shared_ptr<char> osp(new char[1024], std::default_delete<char[]>());

// load the data into your buffer at osp.get()

// Find the offset in the data by parsing
auto const offset = parse_buffer_for_offset(osp.get());

// Now set a new offset into the data
std::shared_ptr<char> nsp(osp, osp.get() + offset);

现在nsp.get()返回偏移地址,但是原始数组将被正确删除。

注意偏移量每个 shared_ptr的属性,因此,如果您复制 shared_ptr nsp得到另一个shared_ptr,它的偏移量相同。无论您构造一个新副本还是将副本分配给现有的shared_ptr,这都行得通。

这意味着您可以使用具有不同偏移量的不同shared_ptr,它们都管理相同的基础资源,这些资源只有在销毁 all shared_ptr之后才会被清除。

要查看运行中的代码,请考虑以下代码:

std::shared_ptr<char> original_sp(new char[1024], std::default_delete<char[]>());

std::shared_ptr<char> offset_100_sp1(original_sp, original_sp.get() + 100);
std::shared_ptr<char> offset_100_sp2 = offset_100_sp1;

std::shared_ptr<char> offset_200_sp1(original_sp, original_sp.get() + 200);
std::shared_ptr<char> offset_200_sp2 = offset_200_sp1;

std::cout << "\nPointers managing the array: " << original_sp.use_count() << '\n';

std::cout << "\nOffset 100 pointers:" << '\n';
std::cout << std::distance(original_sp.get(), offset_100_sp1.get()) << '\n';
std::cout << std::distance(original_sp.get(), offset_100_sp2.get()) << '\n';

std::cout << "\nOffset 200 pointers:" << '\n';
std::cout << std::distance(original_sp.get(), offset_200_sp1.get()) << '\n';
std::cout << std::distance(original_sp.get(), offset_200_sp2.get()) << '\n';

输出:

Pointers managing the array: 5

Offset 100 pointers:
100
100

Offset 200 pointers:
200
200