将shared_ptr设置为new_pointer,即old_pointer + offset

Ale*_*nov 30 c++ smart-pointers shared-ptr pointer-arithmetic

这是一个智能指针:std::shared_ptr<char> p(new char[size])表示填充原始二进制文件内容的数组.在整个数组从文件复制到RAM之后(并且仅在之后),我可以解析它,在此期间我检索一些头信息(几个第一个dwords).然后是实际数据.

在没有提供更多上下文的情况下,将所提到的共享指针设置为实际数据开头的新地址非常方便.该地址仍处于已分配的内存中.但如何设置而不失去它?

一个问题是(是/否):是否可以设置p偏移主流指针,而无需调用数据删除?

Gal*_*lik 42

是的,这是可能的.您可以使用构造函数,此引用中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);
Run Code Online (Sandbox Code Playgroud)

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

注:偏移是一个性质的每个 shared_ptr所以如果你复制shared_ptr nsp你的另一shared_ptr具有相同的偏移.无论您是构造新副本还是将副本分配给现有副本,这都有效shared_ptr.

这意味着您可以shared_ptr使用不同的偏移量来管理相同的底层资源,这些资源只会在所有资源 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';
Run Code Online (Sandbox Code Playgroud)

输出:

Pointers managing the array: 5

Offset 100 pointers:
100
100

Offset 200 pointers:
200
200
Run Code Online (Sandbox Code Playgroud)

  • 是的,这正是别名构造函数的用途! (4认同)