I have a small program where I have a background thread that plays sound, so it needs to run really fast, but it also needs to do a small amount of memory management. I didn't want to use normal new and delete in a time critical area, so I threw this together, but set it up so I could reuse it elsewhere.
template <typename T, unsigned int capacity>
class MemoryPool
{
public:
MemoryPool()
{
for (unsigned int i = 0; i < capacity; i++)
{
myUnusedMemory[i] = &myMemory[i];
}
}
void* operator new(std::size_t size)
{
return myUnusedMemory[myUnusedIndex--];
}
void operator delete(void* ptr)
{
myUnusedMemory[++myUnusedIndex] = (T*)ptr;
}
private:
static int myUnusedIndex;
static T myMemory[capacity];
static T* myUnusedMemory[capacity];
};
template <typename T, unsigned int capacity> int MemoryPool<T, capacity>::myUnusedIndex = capacity-1;
template <typename T, unsigned int capacity> T MemoryPool<T, capacity>::myMemory[capacity];
template <typename T, unsigned int capacity> T* MemoryPool<T, capacity>::myUnusedMemory[capacity];
The intended usage is something like this:
struct Sound : public ag::util::MemoryPool<Sound, 100>
{
// ...
};
Now when calling new Sound()
I get one from my memory pool, which should be super fast. The only things that I can think of that could be improved are making operator new
throw an exception when at capacity. I think I might be able to do away with typename T
. The only reason it's needed is so that myMemory
knows the size of its elements, but I feel like there's another solution here.