Установите shared_ptr с new_pointer, который является old_pointer + offset - PullRequest
0 голосов
/ 17 февраля 2019

Вот умный указатель: std::shared_ptr<char> p(new char[size]), который представляет массив, заполненный необработанным содержимым двоичного файла.После (и только после) весь массив копируется из файла в ОЗУ, я могу его проанализировать, и во время этого я получаю некоторую информацию заголовка (несколько первых двойных слов).Затем следует фактические данные .

Не предоставляя намного больше контекста, мне удобно установить упомянутый общий указатель на новый адрес, который начинается с фактических данных .Этот адрес все еще находится в выделенной памяти.Но как установить, не потеряв его?

Вопрос (да / нет): можно ли установить p на смещение превалирующего указателя, не вызывая удаления данных?

1 Ответ

0 голосов
/ 18 февраля 2019

Да, это возможно.Вы можете использовать конструктор 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_ptrnsp вы получите еще 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
...