Ответ 1
Да, это возможно. Вы можете использовать конструктор 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
с разными смещениями, которые управляют одним и тем же базовым ресурсом, который будет очищен только после уничтожения всех 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