Memory Allocation Tracking [CODE]

From: Sean Butler (sbutler@DEVEAST.COM)
Date: 01/09/98


Below is some code for tracking basic allocation and freeing
of memory.  It has been mildly tested.  It is only to serve
as an example of how you might use existing macros to make
memory tracking easy to implement.

NOTE: this will take quite a bit of memory.
    (8meg on a 32bit machine)

If you dont think you will need that many entries you can of
course reduce MAX_HEAP_ENTRIES

I can only recommend this method fo debug use,
not for everyday use.

/* ------------------------------------------ */
#define MAX_HEAP_ENTRIES 1000000

long heap_entries = 0;      /* number of allocated chunks */
void *heap_tmp = NULL;      /* temp pointer for realloc (in case fails) */
struct heap_data {
    void *address;      /* address of the allocated chunk */
    long bytes;         /* size in bytes of the allocated chunk */
}heap_list[MAX_HEAP_ENTRIES]; /* list of chunks allocated */



#define CREATE(object, size, number, type)                \
    if ((object = (type*) calloc(number, size)) == NULL)  \
        syserr("Failed to allocate memory in CREATE");    \
    else                                                  \
        memalloc(object, size * number);


#define DESTROY(object) \
    memfree(object);    \
    free(object);

#define RECREATE(object, size, number, type)                          \
    heap_tmp = object;                                                \
    if ((object = (type*) realloc(object, number * size)) == NULL) {  \
        syserr("Failed to allocate memory in RECREATE");              \
    heap_tmp = NULL;                                                \
    } else {                                                          \
    memfree(heap_tmp);                                              \
        memalloc(object, size * number);                              \
    }

void memprint(void);
char *str_dup(char *);
void memfree(void *);
void memalloc(void *, size_t);

char *str_dup(char *from)
{
    char *to;

    to = strdup(from);
    if (!to)
    return NULL;
    memal(to, sizeof(char) * strlen(to) + 1); /* Null character counts! */
    return to;
}

void memalloc(void *object, size_t bytes)
{
    int i;
    /* Do we have space to add it */
    if (heap_entries >= MAX_HEAP_ENTRIES) {
        syserr("Too many entries in heap list, can't add another");
        return;
    }
    /* Find a free entry */
    for (i = 0; (heap_list[i].address!=NULL) && i<MAX_HEAP_ENTRIES; i++)
        ;
    if (i >= MAX_HEAP_ENTRIES) {
        syserr("ERROR number of heap entries was incorrect");
        return;
    }
    /* copy the entry */
    heap_list[i].address = object;
    heap_list[i].bytes = bytes;

    /* increase heap_entries */
    heap_entries++;
}

void memfree(void *object)
{
    int i;
    /* find the object in the list */
    for (i = 0;(heap_list[i].address!=object) && i<MAX_HEAP_ENTRIES; i++)
        ;
    if (i >= MAX_HEAP_ENTRIES) {
        syserr("ERROR object not in heap list and free was called.");
        return;
    }
    /* zero that entry in the list */
    heap_list[i].address = NULL;
    heap_list[i].bytes = 0;
    /* decrease heap_entries */
    heap_entries--;
}
/* I just used this for testing, you need a mud-like one for real time */
void memprint()
{
    long bytes = 0;
    long i;
    printf("Allocated blocks: %d\r\n", heap_entries);
    for (i = 0; i < MAX_HEAP_ENTRIES; i++)
        bytes += heap_list[i].bytes;
    printf("Bytes used      : %d\r\n", bytes);
}


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST