Fixed-sized memory pool in C I'm learning C and I am currently implementing a memory pool.

I'm writing it in steps, first I implemented a fixed-sized memory pool then I will try to implement a memory pool with a known size of elements but an unknown number of elements and ultimately try to write a generic one that is just a block of memory that can allocate any size.

The pool is actually a block of memory that is initialized with values that are pointers to the next memory like so:

 ______________
|0x8 |0x10|NULL|
|____|____|____|
 ^    ^    ^
 0x0  0x8  0x10


I want to know if I'm heading in the right direction.
There is the code

allocator.h:

#include &lt;stdlib.h&gt;

typedef struct FixedPoolAllocator FixedPoolAllocator;

FixedPoolAllocator* FixedPoolAllocator_new(size_t nmemb, size_t size);

void* FixedPoolAllocator_alloc(FixedPoolAllocator *allocator);

void FixedPoolAllocator_free(FixedPoolAllocator *allocator, void *ptr);

void FixedPoolAllocator_destroy(FixedPoolAllocator *allocator);


allocator.c:

#include "allocator.h"

#define MAX(a, b) (((a) &gt; (b)) ? (a) : (b))

typedef struct FixedPoolAllocator {

    // The currently free space in which a value can be stored
    size_t *currentFree;
    size_t numOfMembers;
    size_t memberSize;
    // The actual memory block, It is of type char* so that pointer arithmetic will be easier
    char *mem;

} FixedPoolAllocator;

FixedPoolAllocator* FixedPoolAllocator_new(size_t nmemb, size_t size)
{
    if (0 == size || 0 == nmemb) return NULL;

    FixedPoolAllocator *ret = malloc(sizeof *ret);
    if (NULL == ret) return NULL;

    // Make sure that the size of each member is atleast size_t so that the members can store a memory address
    size_t member_size = MAX(sizeof(size_t), size);

    ret-&gt;mem = malloc(nmemb * member_size);
    if (NULL == ret-&gt;mem) return NULL;
    // The initial free member
    ret-&gt;currentFree = (size_t*)ret-&gt;mem;

    ret-&gt;numOfMembers = nmemb;
    ret-&gt;memberSize = size;

    size_t *temp = ret-&gt;currentFree;

    // Assign each member with the address of the next member
    size_t i;
    for (i = 0; i &lt; nmemb - 1; i++) {
        *temp = (size_t) (ret-&gt;mem + (i+1) * member_size);
        temp = (size_t*) ((char*)temp + member_size);
    }

    // The last member points to NULL
    *temp = (size_t)NULL;

    return ret;
}

void* FixedPoolAllocator_alloc(FixedPoolAllocator *allocator)
{
    if (NULL == allocator || NULL == allocator-&gt;currentFree) return NULL;

    // Return the currently free member and update currentFree to the next member in the list
    void *ret = allocator-&gt;currentFree;
    allocator-&gt;currentFree = (size_t*)*allocator-&gt;currentFree;

    return ret;
}

void FixedPoolAllocator_free(FixedPoolAllocator *allocator, void *ptr)
{
    size_t ptr_as_value = (size_t)ptr;

    // Assign the pointed value with the current free member
    *(size_t*)ptr = (size_t)allocator-&gt;currentFree;
    // Update the currenty free member to be the one that was just freed
    allocator-&gt;currentFree = ptr;
}

void FixedPoolAllocator_destroy(FixedPoolAllocator *allocator)
{
    free(allocator-&gt;mem);

    free(allocator);
}
Only a small review

Alignment not guaranteed

temp = (size_t*) ((char*)temp + member_size); attempts to convert a char* to size_t *, yet (char*)temp + member_size is not known to be properly aligned for a size_t*.  Insufficient alignment is undefined behavior.

Detect overflow

As the true product of nmemb * member_size may exceed SIZE_MAX:

if (SIZE_MAX/nmemb &gt; member_size) {
  Handle_Overflow();  // clean-up, return NULL;
}
... =  malloc(nmemb * member_size);


Strange uses of size_t as pointer

// The last member points to NULL *temp = (size_t)NULL; implies something wrong.  If codes needs a pointer, use a pointer, not size_t.  If code needs a size, doesn't use a pointer.  Note that size_t and pointers do not necessarily covert well back and forth.  They might not be the same memory width either.

This use of size_t as a place to encode a pointer is simply broken.  Code needs a new approach.