I faced a problem with std::shared_ptr
. I have a code:
void Receive(const std::shared_ptr<char[]>& data, uint32_t length) {
this->next->Receive(data + 2, length - 2);
}
I need to increment shared_ptr by 2 without losing the ability to delete the memory.
I don't want to copy data, because the data is already in memory and I own the data. It would be foolish to copy the data just to displace and delete the old data if I can just change the pointer without losing performance. Can shared_ptr contain and return one pointer, but delete another?
As far as I know, the internals of shared_ptr contains a pointer to data which is returned by the get()
function and contains a reference to a control block that counts references and is supposed to delete the memory when all references have gone.
So, since it contains pointer separately from control block, maybe I can somehow change it without changing the pointer to the allocated memory block in the control block, without losing the ability to delete the memory? If I can't, maybe I can do it with boost::shared_ptr
?
I haven't checked it yet. I don't use the Boost library, but if it helps me I will.
If shared_ptr::unique returns true, then calling shared_ptr::reset will delete the managed object. However, if shared_ptr::unique returns false, it means there are more than one shared_ptr s sharing ownership of that object.
By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).
The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.
Yes, that's what the aliasing contructor of std::shared_ptr
is for. It keeps the same control block, but it allows you to use another pointer.
The signature is
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;
In your case that would be
void Receive(const std::shared_ptr<char[]>& data, uint32_t length) {
std::shared_ptr<char[]> alias(data, data.get()+2);
this->next->Receive(alias, length - 2);
}
But I do question the use of shared_ptr
in this case. Do you really have shared ownership in this case? Can you not figure out one part of code that could own this memory?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With