Here is a smart pointer: std::shared_ptr<char> p(new char[size])
which represents array filled with raw binary file content. After (and only after) the whole array is copied from file to RAM, I can parse it, and during this I retrieve some header information (a few first dwords). Then actual data follows.
Without giving much more context, it's handy for me to to set mentioned shared pointer to new address that is beginning of actual data. This address is still in alocated memory. But how to set without losing it?
A question is (yes/no): Is it possible to set p
to offset of prevous pointer, without invoking deletion of data?
Yes this is possible. You can use constructor 8
, the aliasing constructor from this reference: 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);
Now nsp.get()
returns the offset address but the original array will get deleted properly.
Note: The offset is a property of each shared_ptr
so if you copy the shared_ptr
nsp
you get another shared_ptr
with the same offset. This works whether you construct a new copy or assign a copy to an existing shared_ptr
.
This means you can have different shared_ptr
with different offsets that all manage the same, underlying resource which will only be cleaned up after all shared_ptr
are destroyed.
To see this in operation consider the following code:
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';
Output:
Pointers managing the array: 5
Offset 100 pointers:
100
100
Offset 200 pointers:
200
200
来源:https://stackoverflow.com/questions/54737556/set-shared-ptr-with-new-pointer-that-is-old-pointer-offset