Okay, here's a custom memory handler I wrote for strings so that I won't have to make a bunch of calls to malloc. I probably won't use it, but it's good practice and might come in handy sometime. The reason I thought this was a good idea was for three reasons.

1. I can get more memory when the program starts, so if I get everything I need and handle it my way then I won't have problems with malloc failing.
2. Instead of having pointers to memory all over the place, I know exactly where it is because each block is one after another. I think this would be good for debugging.
3. Since I only call malloc twice when the program starts, I can get better performance by avoiding expensive malloc calls.

I'm probably an idiot for trying to do this and I know that it's not made very well, but that's why I'm posting it here. Can anyone give me ideas on what to improve, what I'm doing wrong, and if I'm just a complete loser.

The header file, my_mem_handler.h
Code:
#ifndef MY_MEM_HANDLER
#define MY_MEM_HANDLER

#include <stdio.h>
#include <stdlib.h>

/* Exit status */
#define GOOD_EXIT 0
#define BAD_EXIT  1

/* Error handling */
#define ERR_NOMEM     0
#define ERR_FULL_HEAP 1

extern char *err_msg[];

/* Memory handler */
typedef struct {
        char *memory; /* Memory to be referenced */
        unsigned *block_sizes; /* The size of each block referenced */
        unsigned blocks; /* The number of blocks referenced */
        unsigned N_alloc; /* Amount of referenced memory in bytes */
        unsigned N_free; /* Amount of free memory in bytes */
} HEAP;

extern HEAP heap;

/* init_heap allocates memory for the heap
and sets all heap values to their initial settings.
This indicates that no memory has been referenced.
It takes the heap size as an argument. */
int init_heap( unsigned size );

/* free_heap clears all memory allocated to the
heap. */
void free_heap( void );

/* alloc_mem references the first available chunk
of memory of the given size in the heap to mem. It
takes two arguments, the address of the pointer to
be given the reference and the desired size. */
int alloc_mem( char **mem, unsigned size );

/* free_mem returns the chunk of memory referenced
by mem to the heap and sets mem to null. */
void free_mem( char **mem );

#endif
The source file, my_mem_handler.c
Code:
#include "my_mem_handler.h"

char *err_msg[] = {
        "Error, couldn't allocate memory",        /* ERR_NOMEM */
        "Error, not enough heap space available", /* ERR_FULL_HEAP */
};

HEAP heap;

int init_heap( unsigned size )
{
        /* Reserve space for the heap and set it to 0 */
        heap.memory = calloc( size, sizeof( char ) );
        if( !heap.memory ) {
                fputs( err_msg[ERR_NOMEM], stderr );
                return BAD_EXIT;
        }

        /* Reserve space for the block sizes and set it to 0 */
        heap.block_sizes = calloc( size, sizeof( int ) );
        if( !heap.block_sizes ) {
                fputs( err_msg[ERR_NOMEM], stderr );
                return BAD_EXIT;
        }

        heap.blocks = 0;
        heap.N_alloc = 0;
        heap.N_free = size;

        return GOOD_EXIT;
}

void free_heap( void )
{
        free( heap.block_sizes );
        free( heap.memory );
}

int alloc_mem( char **mem, unsigned size )
{
        /* Not enough space on the heap? */
        if( heap.N_free < size ) {
                fputs( err_msg[ERR_FULL_HEAP], stderr );
                return BAD_EXIT;
        }

        /* Set mem to the first free block and reset the heap sizes */
        *mem = heap.memory + heap.N_alloc;
        heap.block_sizes[heap.blocks++] = size;
        heap.N_alloc += size;
        heap.N_free -= size;

        return GOOD_EXIT;
}

void free_mem( char **mem )
{
        heap.blocks--;

        /* Reset the sizes to remove a block */
        heap.N_alloc -= heap.block_sizes[heap.blocks];
        heap.N_free += heap.block_sizes[heap.blocks];

        /* Clear mem */
        *mem = NULL;
}