This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Templated Object Pool Submitted by

Hello flipcoders. I've been having fun with an idea for object pools. What I wanted was a basic object pool designed for fast alocation of fixed size objects. I required operations to create and destroy the object pool, a function to do a fast allocation from it, and also a fast delete (return to pool). Last of all, I required a variable to hold the pool contents, which is passed to the other routines so that the program knows which object pool I am referring to.
I came up with quite an elegant solution IMHO. The AllocateFromObjectPool function is very fast, at the expense of a slow setup in CreateObjectPool. You will notice that the pool is a parameter to every function, this is because I sneakily get the size etc from the variable's type. You can have as many different pools, of whatever types, as you like. Use it like this:

     struct blah {
       short a;
       int b;
       char c;
     };

     blah *pool;
     CreateObjectPool(pool, 10);

     blah *myitem = AllocateFromObjectPool(pool); // (myitem = new blah;)

     ReturnObjectToPool(pool, myitem); // (delete myitem;)

     DeleteObjectPool(pool);

DO NOT try and access the items directly through the pointer to the pool for any reason! Only use these functions on it. It uses a free-list internally, stored at the address pointed to by the pool, so the items are offset in memory. I should probably have wrapped this up in a class to prevent that, but I haven't. Instead of suggesting that, how about DIY? My ultimate aim here is to inspire someone else into writing something even better. I made good use of structs and unions and templates and avoid having to do typecasts like (TItem***) - no I'm not kidding, that was my original plan!
I haven't tested this too extensively, but being quite short it's not likely to contain many bugs. It wont be thread-safe I guess.
Written on a Mac using Symantec C++ v8.6. Permission to use/copy/modify/distribute hereby granted. Do what you want with it - enjoy!
Keep the cotd alive people - contribute! [NZ]_i/\/\alc
(Malcolm)

Download Associated File: MyObjectPool.h (1,703 bytes)

    #ifndef MY_OBJECTPOOL_H
    #define MY_OBJECTPOOL_H

    //Creates an object pool
    //pool: the variable to hold the pool
    //numObj: how many objects required in the pool
    template <class TItem>
    void CreateObjectPool(TItem *&pool, int numObj) {
    	union TElement {
    		TItem *next;
    		TItem item;
    	};
    	pool = (TItem*)(new char[sizeof(TElement) * numObj + sizeof(TItem*)])
    	struct TPool {
    		TItem *freePtr;
    		TElement items[1];
    	} *data = (TPool*)pool;
    	data->freePtr = &data->items[0].item;
    	for (int i=0; i<numObj-1; ++i)
    		data->items[i].next = &data->items[i+1].item;
    	data->items[numObj-1].next = NULL;
    }

    //Destroy the object pool
    //pool: the variable holding the pool to destroy
    template <class TItem>
    void DeleteObjectPool(TItem *pool) {
    	delete[] ((char*)pool);
    }

    //This is essentially replaces your 'new' function
    //pool: the pool you wish to allocate from
    //returns: an object from the pool, or NULL
    template <class TItem>
    TItem *AllocateFromObjectPool(TItem *pool) {
    	union TElement {
    		TItem *next;
    		TItem item;
    	};
    	struct TPool {
    		TItem *freePtr;
    		TElement items[1];
    	} *data = (TPool*)pool;
    	TItem *newObj = data->freePtr;
    	if (newObj != NULL)
    		data->freePtr = ((TElement*)newObj)->next;
    	return newObj;
    }

    //This is essentially replaces your 'delete' function
    //pool: the pool that the object came from
    //oldObj: an object from the pool to return
    template <class TItem>
    void ReturnObjectToPool(TItem *pool, TItem *oldObj) {
    	union TElement {
    		TItem *next;
    		TItem item;
    	};
    	struct TPool {
    		TItem *freePtr;
    		TElement items[1];
    	} *data = (TPool*)pool;
    	((TElement*)oldObj)->next = data->freePtr;
    	data->freePtr = oldObj;
    }

    #endif

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.