diff --git a/src/lib/allocationcluster.cpp b/src/lib/allocationcluster.cpp index 868496a22..1f76fed72 100644 --- a/src/lib/allocationcluster.cpp +++ b/src/lib/allocationcluster.cpp @@ -60,7 +60,7 @@ namespace lib { typedef std::vector MemTable; TypeInfo type_; MemTable mem_; - size_t top_; + size_t top_; ///< index of the next slot available for allocation public: MemoryManager(TypeInfo info) : top_(0) { reset(info); } @@ -72,6 +72,9 @@ namespace lib { void* allocate(); void commit (void* pendingAlloc); + + private: + void clearStorage(); }; @@ -101,11 +104,20 @@ namespace lib { REQUIRE (top_ == mem_.size() || (top_+1) == mem_.size()); while (top_) - type_.killIt (&mem_[--top_]); - mem_.clear(); + type_.killIt (mem_[--top_]); + clearStorage(); }// note: unnecessary to kill pending allocations + inline void + AllocationCluster::MemoryManager::clearStorage() + { + for (size_t i=mem_.size(); 0 < i; ) + delete[] mem_[--i]; + mem_.clear(); + } + + inline void* AllocationCluster::MemoryManager::allocate() { @@ -116,9 +128,11 @@ namespace lib { if (top_==mem_.size()) mem_.resize(top_+1); - mem_[top_] = new char[type_.allocSize]; + if (!mem_[top_]) + mem_[top_] = new char[type_.allocSize]; ENSURE (top_ < mem_.size()); + ENSURE (mem_[top_]); return mem_[top_]; } @@ -165,7 +179,8 @@ namespace lib { TRACE (buildermem, "shutting down AllocationCluster"); for (size_t i = typeHandlers_.size(); 0 < i; --i) - handler(i)->purge(); + if (handler(i)) + handler(i)->purge(); typeHandlers_.clear(); diff --git a/tests/common/allocationclustertest.cpp b/tests/common/allocationclustertest.cpp index 001326ce1..4b5d1f458 100644 --- a/tests/common/allocationclustertest.cpp +++ b/tests/common/allocationclustertest.cpp @@ -66,9 +66,9 @@ namespace lib { { char id = i1 + i2 + i3; content[0] = id; + checksum += id; if (0 == (rand() % 20)) throw id; - checksum += id; } ~Dummy() @@ -209,8 +209,8 @@ namespace lib { } catch (char id) { - checksum -= id; - } + checksum -= id; // exception thrown from within constructor, + } // thus dtor won't be called. Repair the checksum! } ASSERT (0==checksum); }