I use an external library which operates on large quantities of data. The data is passed in by a raw pointer, plus the length. The library does not claim ownership of the pointer, but invokes a provided callback function (with the same two arguments) when it is done with the data.
The data gets prepared conveniently by using std::vector<T>
, and I'd rather not give up this convenience. Copying the data is completely out of the question. Thus, I need a way to "take over" the memory buffer owned by an std::vector<T>
, and (later on) deallocate it in the callback.
My current solution looks as follows:
std::vector<T> input = prepare_input();
T * data = input.data();
size_t size = input.size();
// move the vector to "raw" storage, to prevent deallocation
alignas(std::vector<T>) char temp[sizeof(std::vector<T>)];
new (temp) std::vector<T>(std::move(input));
// invoke the library
lib::startProcesing(data, size);
and, in the callback function:
void callback(T * data, size_t size) {
std::allocator<T>().deallocate(data, size);
}
This solution works, because the standard allocator's deallocate
function ignores its second argument (the element count) and simply calls ::operator delete(data)
. If it did not, bad things could happen, as the size
of the input vector might be quite a bit smaller than its capacity
.
My question is: is there a reliable (wrt. the C++ standard) way of taking over the buffer of std::vector
and releasing it "manually" at some later time?
You can't take ownership of the memory from a vector, but you can solve your underlying problem another way.
Here's how I'd approach it - its a bit hacky because of the static global variable and not thread safe, but it can be made so with some simple locking around accesses to the
registry
object.Now you can just do
But watch out! Bad things will happen if you add/remove elements to the input after you've called
my_startProcessing
- the buffer the library has may be invalidated. (You may be allowed to change values in the vector, as I believe that will write through the to data correctly, but that will depend on what the library allows too.)Also this doesn't work if
T
=bool
sincestd::vector<bool>::data()
doesn't work.