I am using boost multiprecision with the gmp backend. Consider the following code to construct a multiprecision number from a binary representation:
typedef boost::multiprecision::mpz_int BigInt;
BigInt createNumber(const unsigned char* in, size_t length)
{
mpz_t number;
mpz_init2(number, length);
mpz_import(number, 1, 1, length, 1, 0, in);
BigInt id(number);
mpz_clear(number);
return number;
}
I was under the impression that the call to mpz_clear(number)´ is required to not leak the
mpz_t, because the
boost::multiprecision::mpz_intconstructor copies the value of the
mpz_t` and therefore takes no ownership of it. By using the debugger I figured out that this constructor is called:
gmp_int(const mpz_t val)
{
mpz_init_set(this->m_data, val);
}
This seems to confirm my suspicion since mpz_init_set initializes the internal mpz_t
variable with the value of the operand instead of just copying the mpz_t
.
But when I do the mpz_clear(number)
to free the memory I get wrong values for the constructed BigInt
. Removing the mpz_clear(number)
yields the correct result. What am I missing here?
Okay after crafting this answer and looking at the code I saw the mistake. I was returning the number
when I should be returning the id
. This is why conversion constructors should be explicit :)
So yes the constructor does copy the mpz_int. But I was freeing it before it could be copied (on function return). In addition I leaked one mpz_t every time.