fixed a rather obscure memory bug, which also simplified some code

This commit is contained in:
John Wiegley 2004-09-24 05:25:52 -04:00
parent 3038b7cee8
commit c5d519447e
4 changed files with 13 additions and 43 deletions

View file

@ -84,33 +84,6 @@ _init_amounts::~_init_amounts()
true_value.ref--; true_value.ref--;
} }
void clean_commodity_history(char * item_pool, char * item_pool_end)
{
for (commodities_map::iterator i = commodity_t::commodities.begin();
i != commodity_t::commodities.end();
i++)
for (history_map::iterator j = (*i).second->history.begin();
j != (*i).second->history.end();
j++) {
amount_t::bigint_t * quantity = (*j).second.quantity;
if (quantity &&
(char *)quantity >= item_pool &&
(char *)quantity < item_pool_end) {
assert(quantity->flags & BIGINT_BULK_ALLOC);
// Since the journal in which this price was bulk alloc'd (on
// reading from a binary file) is going away, we must make a
// new copy of the value, because other journals might still
// be using it.
amount_t::bigint_t * q = new amount_t::bigint_t(*quantity);
if (--quantity->ref == 0)
quantity->~bigint_t();
(*j).second.quantity = q;
}
}
}
static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
{ {
// Round `value', with an encoding precision of `value_prec', to a // Round `value', with an encoding precision of `value_prec', to a
@ -238,8 +211,14 @@ void amount_t::_copy(const amount_t& amt)
if (quantity) if (quantity)
_release(); _release();
quantity = amt.quantity; // Never maintain a pointer into a bulk allocation pool; such
quantity->ref++; // pointers are not guaranteed to remain.
if (amt.quantity->flags & BIGINT_BULK_ALLOC) {
quantity = new bigint_t(*amt.quantity);
} else {
quantity = amt.quantity;
quantity->ref++;
}
} }
commodity_ = amt.commodity_; commodity_ = amt.commodity_;
} }

View file

@ -354,8 +354,6 @@ bool account_t::valid() const
return true; return true;
} }
void clean_commodity_history(char * item_pool, char * item_pool_end);
journal_t::~journal_t() journal_t::~journal_t()
{ {
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t"); DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
@ -374,9 +372,6 @@ journal_t::~journal_t()
else else
(*i)->~entry_t(); (*i)->~entry_t();
// Remove historical prices which were allocated in the item_pool.
clean_commodity_history(item_pool, item_pool_end);
if (item_pool) if (item_pool)
delete[] item_pool; delete[] item_pool;
} }

View file

@ -305,13 +305,8 @@ int parse_and_report(int argc, char * argv[], char * envp[])
if (config.use_cache && config.cache_dirty && if (config.use_cache && config.cache_dirty &&
! config.cache_file.empty()) { ! config.cache_file.empty()) {
if (access(config.cache_file.c_str(), W_OK) == -1) { std::ofstream stream(config.cache_file.c_str());
std::cerr << "Warning: Cannot update cache file '" write_binary_journal(stream, journal.get(), &journal->sources);
<< config.cache_file << "'" << std::endl;
} else {
std::ofstream stream(config.cache_file.c_str());
write_binary_journal(stream, journal.get(), &journal->sources);
}
} }
return 0; return 0;

View file

@ -87,10 +87,11 @@ else:
text_parser = TextualParser () text_parser = TextualParser ()
bin_parser = BinaryParser () bin_parser = BinaryParser ()
qif_parser = QifParser () qif_parser = QifParser ()
gnucash_parser = None
try: try:
gnucush_parser = GnucashParser () gnucash_parser = GnucashParser ()
except: except:
gnucush_parser = None pass
register_parser (text_parser) register_parser (text_parser)
register_parser (bin_parser) register_parser (bin_parser)