zenno2
zenno2

Reputation: 453

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.

Upvotes: 10

Views: 1498

Answers (1)

PeterT
PeterT

Reputation: 8284

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?

Upvotes: 15

Related Questions