bool FixedAllocator::MakeNewChunk( void ) { bool allocated = false; try { std::size_t size = chunks_.size(); // Calling chunks_.reserve *before* creating and initializing the new // Chunk means that nothing is leaked by this function in case an // exception is thrown from reserve. if ( chunks_.capacity() == size ) { if ( 0 == size ) size = 4; chunks_.reserve( size * 2 ); } Chunk newChunk; allocated = newChunk.Init( blockSize_, numBlocks_ ); if ( allocated ) chunks_.push_back( newChunk ); } catch ( ... ) { allocated = false; } if ( !allocated ) return false; allocChunk_ = &chunks_.back(); deallocChunk_ = &chunks_.front(); return true; }
void * FixedAllocator::Allocate() { if (!last_alloc_ || last_alloc_->blocks_available_ == 0) { // no memory available in the cached chunk, try to find one. Chunks::iterator e = chunks_.end(); Chunks::iterator i = chunks_.begin(); for (; i!=e; ++i) { if (i->blocks_available_ > 0) { // found a chunk! last_alloc_ = &*i; break; } } if (i == e) { // no chunks have blocks available, add a new one. chunks_.reserve(chunks_.size()+1); MemChunk chunk; chunk.Init(block_size_, blocks_); chunks_.push_back(chunk); last_alloc_ = &chunks_.back(); last_dealloc_ = &chunks_.back(); } } // chunk pointer vaild check assert(last_alloc_ != NULL); assert(last_alloc_->blocks_available_ > 0); return last_alloc_->Allocate(block_size_); }