I'm tring to encapsulate a C module into C++ classes.
In the C implementation there is a function returing a pointer to a static const
const BIGNUM *BN_value_one(void)
{
static const BN_ULONG data_one = 1L;
static const BIGNUM const_one =
{ (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
return (&const_one);
}
I'm tring to make it a static method in a class with a destructor doing some releasing actions
class BigNumber
{
struct deleter
{
void operator() (BIGNUM *it)
{
BN_free(it); // The freeing operation provided by origin C library
}
};
using BN_ptr = std::unique_ptr<BIGNUM, deleter>;
/* The OpenSSL BIGNUM pointer */
BN_ptr bn;
public:
BigNumber() : bn(BN_new(), ::BN_free) {}
BigNumber(BigNumber &&other) : bn(std::move(other.bn)) {}
BigNumber(const BigNumber &other) : bn(BN_new(), ::BN_free)
{
::BN_copy(bn.get(), other.bn.get());
}
BigNumber(BIGNUM *src) : bn(src, ::BN_free) {}
static const BigNumber one()
{
static const BigNumber o(const_cast<BIGNUM *>(::BN_value_one()));
return o;
}
}
Since the one()
method returning a unique_ptr
to a static variable in BN_value_one
, it will occurs a segmentation fault when destructing the returned value.
Is there any way the avoid such destruction, or any better encapsulation?
As you're using the openssl library you don't have to use BN_free()
because your code never allocated a BIGNUM
with BN_new()
. For more explanation see this manpage .
So you don't need the unique_ptr
nor the deleter.
Edit #1:
I see that your class can also hold allocated BIGNUM
values. So there are two possibilities to distinguish between allocated and not allocated BIGNUM
values.
unique_ptr
. BN_free()
. Edit #2:
Now your code is more complete. You could write an addional constructor that takes a pointer to a const BIGNUM
that uses an own dummy free function. You have to avoid the const_cast
if you use this constructor.
BigNumber(const BIGNUM *src) : bn(src, ::BN_dummy_free) {}
The dummy free should look like this:
void BN_dummy_free(BIGNUM *a) {}
That should work with your code and will not end in a segmentation fault. So you could take allocated and non allocated BIGNUMs.
Also you should take care at your copy constructor, because it will always use BN_free()
. You should copy the used deleter function, which could may be the BN_dummy_free()
function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.