How to handle a scenario where I have a unique pointer with custom deleter, but a 3rd party library's function expects a raw pointer and I pass the stored pointer in the unique_ptr with .get(), but this function takes ownership of the raw pointer.
Example:
Initialize the unique pointers with custom deleter:
std::unique_ptr<BIGNUM, decltype(&BN_free)> r(BN_bin2bn(signature.data(), bnLen, nullptr), &BN_free);
std::unique_ptr<BIGNUM, decltype(&BN_free)> s(BN_bin2bn(signature.data() bnLen, bnLen, nullptr), &BN_free);
Pass them to the ECDSA_SIG function, which takes the ownership of the r and s unique pointers:
ECDSA_SIG_set0(ecDsaSignature.get(), r.get(), s.get()))
At the end of the scope the custom deleter is called, but it crashes because the r and s were moved. I was thinking about using raw pointers, but what happens if the ECDSA_SIG_set0 function call is unsuccessful, do I have to manually free the r and s variables? Is this the correct way, or is there a more elegant way to handle this scenario?
Thank you in advance.
CodePudding user response:
I pass the stored pointer in the unique_ptr with .get(), but this function takes ownership of the raw pointer.
If the function takes ownership, then you should release the ownership from the unique pointer. Otherwise the ownership won't be unique and you will get undefined behaviour due to multiple calls to the deleter. This is what the release
member function is for.
but what happens if the ECDSA_SIG_set0 function call is unsuccessful, do I have to manually free the r and s variables?
If the function takes ownership of the pointer, then it is responsible for deleting it (until it transfers the ownership somewhere else). If the function sometimes leaks the pointer, then it is a badly designed API.
What the function does should be specified in its documentation. It would be much better to use std::unique_ptr
in the API if it takes ownership.