rgaillard rgaillard - 4 months ago 20
C++ Question

Replace malloc and free by new and delete in a memory pool

I am using a templated memory pool that uses the following union to store the data:

union MemoryPoolNode
{
MemoryPoolNode *next;
T data;
};


Previously, I was allocating memory for a new node using malloc:

MemoryPoolNode *node = (MemoryPoolNode*)malloc(sizeof(MemoryPoolNode));


And to free it:

free(node);


Now, I want to replace my calls to malloc and free by new and delete.

For this purpose, to allocate memory for a node, I'm now doing:

MemoryPoolNode *node = (MemoryPoolNode*)new char[sizeof(MemoryPoolNode)];


And to free it:

char *toDelete = (char*)node;
delete[] toDelete;


Is it the right way to do it?

The type T in my union can be a class with a constructor and a destructor and I don't want the constructor nor the destructor to be called when I allocate memory for new node in my memory pool because I already use the placement new and I call the destructor manually each time a node is popped and put back in the memory pool, so I just want to allocate and free memory, just like malloc and free would do.

FYI, I'm replacing malloc and free because the pool is used in an environment where "new" and "delete" can have been overridden to allocate memory accordingly (user space, kernel, ...).

Answer

Your code is broken and you need to fix it first.

Pre-C++11:

Unions cannot contain a non-static data member with a non-trivial special member function (copy constructor, copy-assignment operator, or destructor).

Post-C++11:

If a union contains a non-static data member with a non-trivial special member function (default constructor, copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer.

See here. You follow neither rule. You need to fix this.

Once you fix it, you can just use node = new MemoryPoolNode() and delete node;.

For C++11, this will do:

union MemoryPoolNode
{
    MemoryPoolNode *next;
    T data;

    MemoryPoolNode() : next(NULL) { ; }
    ~MemoryPoolNode() { ; }
};