I'm working on a memory pool/memory allocator implementation and I am setting it up in a manor where only a special "Client" object type can draw from the pool.The client can either be constructed directly onto the pool, or it can use the pool for dynamic memory calls or it could in theory do both. I would like to be able to overload operator new and operator delete in a way that would call my pools "alloc()" and "free()" functions in order to get the memory needed for the object to construct upon.
One of the main issues that I am having is getting my operator delete to be able to free up the memory by calling the pool->free() function I have written. I came up with a hack that fixes it by passing the pool into the constructor and having the destructor do the deallocation work. This is all fine and dandy until someone needs to inherit from this class and override the destructor for their own needs and then forgets to do the memory deallocations. Which is why i want to wrap it all up in the operators so the functionality is tucked away and inherited by default.
My Code Is on GitHub here: https://github.com/zyvitski/Pool
My class definition for the Client is as follows:
class Client
{
public:
Client();
Client(Pool* pool);
~Client();
void* operator new(size_t size,Pool* pool);
void operator delete(void* memory);
Pool* m_pPool;
};
And the implementation is:
Client::Client()
{
}
Client::Client(Pool* pool)
{
m_pPool = pool;
}
Client::~Client()
{
void* p = (void*)this;
m_pPool->Free(&p);
m_pPool=nullptr;
}
void* Client::operator new(size_t size, Pool* pool)
{
if (pool!=nullptr) {
//use pool allocator
MemoryBlock** memory=nullptr;
memory = pool->Alloc(size);
return *memory;
}
else throw new std::bad_alloc;
}
void Client::operator delete(void* memory)
{
//should somehow free up the memory back to the pool
// the proper call will be:
//pool->free(memory);
//where memory is the address that the pool returned in operator new
}
Here is the example Main() that i'm using for the moment:
int main(int argc, const char * argv[]){
Pool* pool = new Pool();
Client* c = new(pool) Client(pool);
/*
I'm using a parameter within operator new to pass the pool in for use and i'm also passing the pool as a constructor parameter so i can free up the memory in the destructor
*/
delete c;
delete pool;
return 0;
}
So far my code works, but I want to know if there is a better way to achieve this? Please let me know if anything I am asking/doing is simply impossible, bad practice or just simply dumb. I am on a MacBook Pro right now but i would like to keep my code cross platform if at all possible.
If you have any questions that would help you help me do let me know.
And of course, Thanks in advance to anyone who can help.