diff options
author | John Wiegley <johnw@newartisans.com> | 2008-07-22 21:58:00 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-07-22 21:58:00 -0400 |
commit | 14de0694a95ecd494d5d45f91e30ab9bee06182a (patch) | |
tree | 3f3ac0cca20e7274b7dfe2013c7a4834a5297dc4 /value.cc | |
parent | f0f2b34ea9db64bdabe65119d3fd265308e6d205 (diff) | |
download | fork-ledger-14de0694a95ecd494d5d45f91e30ab9bee06182a.tar.gz fork-ledger-14de0694a95ecd494d5d45f91e30ab9bee06182a.tar.bz2 fork-ledger-14de0694a95ecd494d5d45f91e30ab9bee06182a.zip |
Fixed a memory bug due to a shallow copy in value_t::storage_t.
Diffstat (limited to 'value.cc')
-rw-r--r-- | value.cc | 61 |
1 files changed, 40 insertions, 21 deletions
@@ -36,6 +36,45 @@ namespace ledger { intrusive_ptr<value_t::storage_t> value_t::true_value; intrusive_ptr<value_t::storage_t> value_t::false_value; +value_t::storage_t& value_t::storage_t::operator=(const value_t::storage_t& rhs) +{ + type = rhs.type; + + switch (type) { + case DATETIME: + new((datetime_t *) data) datetime_t(*(datetime_t *) rhs.data); + break; + + case AMOUNT: + new((amount_t *) data) amount_t(*(amount_t *) rhs.data); + break; + + case BALANCE: + *(balance_t **) data = new balance_t(**(balance_t **) rhs.data); + break; + + case BALANCE_PAIR: + *(balance_pair_t **) data = + new balance_pair_t(**(balance_pair_t **) rhs.data); + break; + + case STRING: + new((string *) data) string(*(string *) rhs.data); + break; + + case SEQUENCE: + *(sequence_t **) data = new sequence_t(**(sequence_t **) rhs.data); + break; + + default: + // The rest are fundamental types, which can copy using std::memcpy + std::memcpy(data, rhs.data, sizeof(data)); + break; + } + + return *this; +} + void value_t::storage_t::destroy() { switch (type) { @@ -119,28 +158,8 @@ void value_t::shutdown() void value_t::_dup() { assert(storage); - if (storage->refc > 1) { + if (storage->refc > 1) storage = new storage_t(*storage.get()); - - // If the data referenced by storage is an allocated pointer, we - // need to create a new object in order to achieve duplication. - switch (storage->type) { - case BALANCE: - *(balance_t **) storage->data = - new balance_t(**(balance_t **) storage->data); - break; - case BALANCE_PAIR: - *(balance_pair_t **) storage->data = - new balance_pair_t(**(balance_pair_t **) storage->data); - break; - case SEQUENCE: - *(sequence_t **) storage->data = - new sequence_t(**(sequence_t **) storage->data); - break; - default: - break; // everything else has been duplicated - } - } } value_t::operator bool() const |