Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change the pointer in shared_ptr without losing the ability to delete the memory?

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.

like image 476
zenno2 Avatar asked Jul 13 '21 14:07

zenno2


People also ask

Does shared pointer call Delete?

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.

What happens when you move a shared_ptr?

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).

What happens when shared_ptr goes out of scope?

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.


1 Answers

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?

like image 176
PeterT Avatar answered Nov 15 '22 21:11

PeterT