tracked down a tricky memory leak in value.h
This commit is contained in:
parent
7dbd7bce59
commit
86ac953379
2 changed files with 86 additions and 78 deletions
52
amount.cc
52
amount.cc
|
|
@ -34,12 +34,16 @@ class amount_t::bigint_t {
|
||||||
bigint_t() : prec(0), ref(1), index(0) {
|
bigint_t() : prec(0), ref(1), index(0) {
|
||||||
mpz_init(val);
|
mpz_init(val);
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"ctor " << this << " " << bigint_ctors);
|
||||||
bigint_ctors++;
|
bigint_ctors++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
bigint_t(mpz_t _val) : prec(0), ref(1), index(0) {
|
bigint_t(mpz_t _val) : prec(0), ref(1), index(0) {
|
||||||
mpz_init_set(val, _val);
|
mpz_init_set(val, _val);
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"ctor " << this << " " << bigint_ctors);
|
||||||
bigint_ctors++;
|
bigint_ctors++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -47,15 +51,19 @@ class amount_t::bigint_t {
|
||||||
: prec(other.prec), ref(1), index(0) {
|
: prec(other.prec), ref(1), index(0) {
|
||||||
mpz_init_set(val, other.val);
|
mpz_init_set(val, other.val);
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"ctor " << this << " " << bigint_ctors);
|
||||||
bigint_ctors++;
|
bigint_ctors++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
~bigint_t() {
|
~bigint_t() {
|
||||||
assert(ref == 0);
|
assert(ref == 0);
|
||||||
mpz_clear(val);
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"dtor " << this << " " << bigint_dtors);
|
||||||
bigint_dtors++;
|
bigint_dtors++;
|
||||||
#endif
|
#endif
|
||||||
|
mpz_clear(val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -131,6 +139,10 @@ static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chop off the rounded bits
|
||||||
|
mpz_ui_pow_ui(divisor, 10, value_prec - round_prec);
|
||||||
|
mpz_tdiv_q(out, out, divisor);
|
||||||
|
|
||||||
mpz_clear(quotient);
|
mpz_clear(quotient);
|
||||||
mpz_clear(remainder);
|
mpz_clear(remainder);
|
||||||
}
|
}
|
||||||
|
|
@ -185,6 +197,8 @@ amount_t::amount_t(const double value)
|
||||||
|
|
||||||
void amount_t::_release()
|
void amount_t::_release()
|
||||||
{
|
{
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"bigint " << quantity << " --ref " << (quantity->ref - 1));
|
||||||
if (--quantity->ref == 0)
|
if (--quantity->ref == 0)
|
||||||
delete quantity;
|
delete quantity;
|
||||||
}
|
}
|
||||||
|
|
@ -217,6 +231,8 @@ void amount_t::_copy(const amount_t& amt)
|
||||||
|
|
||||||
quantity = amt.quantity;
|
quantity = amt.quantity;
|
||||||
quantity->ref++;
|
quantity->ref++;
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"bigint " << quantity << " ++ref " << quantity->ref);
|
||||||
}
|
}
|
||||||
commodity = amt.commodity;
|
commodity = amt.commodity;
|
||||||
}
|
}
|
||||||
|
|
@ -322,11 +338,15 @@ void amount_t::_resize(unsigned int prec)
|
||||||
|
|
||||||
amount_t& amount_t::operator+=(const amount_t& amt)
|
amount_t& amount_t::operator+=(const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (amt.quantity) {
|
if (! amt.quantity)
|
||||||
|
return *this;
|
||||||
|
|
||||||
if (! quantity) {
|
if (! quantity) {
|
||||||
quantity = new bigint_t(*amt.quantity);
|
quantity = new bigint_t(*amt.quantity);
|
||||||
commodity = amt.commodity;
|
commodity = amt.commodity;
|
||||||
} else {
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
_dup();
|
_dup();
|
||||||
|
|
||||||
if (commodity != amt.commodity)
|
if (commodity != amt.commodity)
|
||||||
|
|
@ -343,19 +363,22 @@ amount_t& amount_t::operator+=(const amount_t& amt)
|
||||||
temp._resize(quantity->prec);
|
temp._resize(quantity->prec);
|
||||||
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
|
mpz_add(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_t& amount_t::operator-=(const amount_t& amt)
|
amount_t& amount_t::operator-=(const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (amt.quantity) {
|
if (! amt.quantity)
|
||||||
|
return *this;
|
||||||
|
|
||||||
if (! quantity) {
|
if (! quantity) {
|
||||||
quantity = new bigint_t(*amt.quantity);
|
quantity = new bigint_t(*amt.quantity);
|
||||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||||
commodity = amt.commodity;
|
commodity = amt.commodity;
|
||||||
} else {
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
_dup();
|
_dup();
|
||||||
|
|
||||||
if (commodity != amt.commodity)
|
if (commodity != amt.commodity)
|
||||||
|
|
@ -372,8 +395,7 @@ amount_t& amount_t::operator-=(const amount_t& amt)
|
||||||
temp._resize(quantity->prec);
|
temp._resize(quantity->prec);
|
||||||
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
|
mpz_sub(MPZ(quantity), MPZ(quantity), MPZ(temp.quantity));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -598,11 +620,7 @@ amount_t amount_t::round(unsigned int prec) const
|
||||||
amount_t temp = *this;
|
amount_t temp = *this;
|
||||||
temp._dup();
|
temp._dup();
|
||||||
mpz_round(MPZ(temp.quantity), MPZ(temp.quantity), quantity->prec, prec);
|
mpz_round(MPZ(temp.quantity), MPZ(temp.quantity), quantity->prec, prec);
|
||||||
#if 0
|
|
||||||
mpz_ui_pow_ui(divisor, 10, quantity->prec - prec);
|
|
||||||
mpz_tdiv_q(MPZ(temp.quantity), MPZ(temp.quantity), divisor);
|
|
||||||
quantity->prec = prec;
|
quantity->prec = prec;
|
||||||
#endif
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -626,10 +644,8 @@ std::ostream& operator<<(std::ostream& out, const amount_t& amt)
|
||||||
// outputting it. NOTE: `rquotient' is used here as a temp variable!
|
// outputting it. NOTE: `rquotient' is used here as a temp variable!
|
||||||
|
|
||||||
if (amt.commodity->precision < amt.quantity->prec) {
|
if (amt.commodity->precision < amt.quantity->prec) {
|
||||||
mpz_round(rquotient, MPZ(amt.quantity),
|
mpz_round(rquotient, MPZ(amt.quantity), amt.quantity->prec,
|
||||||
amt.quantity->prec, amt.commodity->precision);
|
amt.commodity->precision);
|
||||||
mpz_ui_pow_ui(divisor, 10, amt.quantity->prec - amt.commodity->precision);
|
|
||||||
mpz_tdiv_q(rquotient, rquotient, divisor);
|
|
||||||
mpz_ui_pow_ui(divisor, 10, amt.commodity->precision);
|
mpz_ui_pow_ui(divisor, 10, amt.commodity->precision);
|
||||||
mpz_tdiv_qr(quotient, remainder, rquotient, divisor);
|
mpz_tdiv_qr(quotient, remainder, rquotient, divisor);
|
||||||
}
|
}
|
||||||
|
|
@ -928,6 +944,8 @@ void amount_t::read_quantity(std::istream& in)
|
||||||
assert(index <= bigints.size());
|
assert(index <= bigints.size());
|
||||||
quantity = bigints[index - 1];
|
quantity = bigints[index - 1];
|
||||||
quantity->ref++;
|
quantity->ref++;
|
||||||
|
DEBUG_PRINT("ledger.amount.bigint-show",
|
||||||
|
"bigint " << quantity << " ++ref " << quantity->ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
24
value.h
24
value.h
|
|
@ -17,8 +17,6 @@ namespace ledger {
|
||||||
|
|
||||||
class value_t
|
class value_t
|
||||||
{
|
{
|
||||||
bool constructed;
|
|
||||||
|
|
||||||
value_t(const value_t& copy);
|
value_t(const value_t& copy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -32,23 +30,24 @@ class value_t
|
||||||
ANY
|
ANY
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
value_t() : constructed(false) {
|
value_t() {
|
||||||
*this = 0U;
|
*((unsigned int *) data) = 0;
|
||||||
|
type = INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t(const bool value) : constructed(false) {
|
value_t(const bool value) {
|
||||||
*((bool *) data) = value;
|
*((bool *) data) = value;
|
||||||
type = BOOLEAN;
|
type = BOOLEAN;
|
||||||
}
|
}
|
||||||
value_t(const unsigned int value) : constructed(false) {
|
value_t(const unsigned int value) {
|
||||||
*((unsigned int *) data) = value;
|
*((unsigned int *) data) = value;
|
||||||
type = INTEGER;
|
type = INTEGER;
|
||||||
}
|
}
|
||||||
value_t(const amount_t& value) : constructed(true) {
|
value_t(const amount_t& value) {
|
||||||
new((amount_t *)data) amount_t(value);
|
new((amount_t *)data) amount_t(value);
|
||||||
type = AMOUNT;
|
type = AMOUNT;
|
||||||
}
|
}
|
||||||
value_t(const balance_t& value) : constructed(true) {
|
value_t(const balance_t& value) {
|
||||||
new((balance_t *)data) balance_t(value);
|
new((balance_t *)data) balance_t(value);
|
||||||
type = BALANCE;
|
type = BALANCE;
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +57,6 @@ class value_t
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (constructed) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
((amount_t *)data)->~amount_t();
|
((amount_t *)data)->~amount_t();
|
||||||
|
|
@ -69,8 +67,6 @@ class value_t
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
constructed = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t& operator=(const bool value) {
|
value_t& operator=(const bool value) {
|
||||||
|
|
@ -845,11 +841,9 @@ class value_t
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
new((amount_t *)data) amount_t(*((bool *) data));
|
new((amount_t *)data) amount_t(*((bool *) data));
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
new((balance_t *)data) balance_t(*((bool *) data));
|
new((balance_t *)data) balance_t(*((bool *) data));
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -867,11 +861,9 @@ class value_t
|
||||||
break;
|
break;
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
new((amount_t *)data) amount_t(*((unsigned int *) data));
|
new((amount_t *)data) amount_t(*((unsigned int *) data));
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
new((balance_t *)data) balance_t(*((unsigned int *) data));
|
new((balance_t *)data) balance_t(*((unsigned int *) data));
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -900,7 +892,6 @@ class value_t
|
||||||
amount_t temp = *((amount_t *) data);
|
amount_t temp = *((amount_t *) data);
|
||||||
destroy();
|
destroy();
|
||||||
new((balance_t *)data) balance_t(temp);
|
new((balance_t *)data) balance_t(temp);
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -928,7 +919,6 @@ class value_t
|
||||||
amount_t temp = ((balance_t *) data)->amount();
|
amount_t temp = ((balance_t *) data)->amount();
|
||||||
destroy();
|
destroy();
|
||||||
new((amount_t *)data) amount_t(temp);
|
new((amount_t *)data) amount_t(temp);
|
||||||
constructed = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BALANCE:
|
case BALANCE:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue