0

I have a library which contains a function that returns the following:

std::shared_ptr<const uint8_t[]>
and
uint32_t size

I need it to pass it to another API that takes:

std::vector<uint8_t> data

The data contained in the shared_ptr is the exact same data that needs to go into the vector, so a move operation would be ideal.

So my question is this: Is there any way to obtain this without just copying the data? I realize the issue hinges on the fact that shared_ptr will delete the data once it goes out of scope, so I'd like to know if there's a way to circumvent this.

(And if copy is necessary, what is the most efficient method to do so? I'm thinking std::copy or good'ol' memcpy.)

SupAl
  • 517
  • 3
  • 12

1 Answers1

2

No, it isn't possible for a vector to take ownership of a separately allocated array.

If you need a vector, and the source isn't a vector, then you have to copy (you could move individual elements, but that's same as copying in case of std::uint8_t).

If you wish to avoid a copy, then you must change one of the premises: Either start with a vector (if library permits), or don't create a vector.

I'm thinking std::copy or good'ol' memcpy.

The only reason to use std::memcpy over std::copy is to reinterpret the data (std::copy could be used for that as well, but the syntax becomes clunky with the casts that are necessary) which you aren't doing here.

std::copy is fine as well as the vector constructor that accepts a pair of iterators.

I realize the issue hinges on the fact that shared_ptr will delete the data once it goes out of scope, so I'd like to know if there's a way to circumvent this.

Your intuition is correct that releasing the pointer from ownership of the shared pointer would have been necessary in order to achieve what you want. However, it isn't sufficient since you cannot make vector take that ownership.

But regarding whether there's a way to prevent a shared pointer from deleting the owned pointer: Yes, it is possible by writing a custom deleter class. But the library that creates the shared pointer would have to let you be in control of the deleter which I suspect isn't the case.

This would also be quite dangerous since you would have to make sure that whatever takes ownership of the pointer would have to keep it alive at least as long as the longest living shared pointer to the "released" data... which is quite difficult unless you're in control of all of the shared owners.

eerorika
  • 232,697
  • 12
  • 197
  • 326