cpointersmemorymemory-address

How can this code know exactly that pMem will always be the value of MAGIC_NUM?


I'm working on a legacy MUD codebase, and I've been getting the bug message in this block of code. I'm trying to understand it, but also I'm wondering how it's even able to ever work? Aren't addresses always random? Thanks for your help!

/*
 * Give a GP block back to the memory manager for recycling.
 */
void free_mem(void *pMem, size_t sMem) {
    int iList;

#ifdef MAGIC_CHECKING
    int *magic;

    pMem = (void *)(((char *)pMem) - sizeof(*magic));
    magic = (int *)pMem;

#ifndef MAGIC_NUM
#define MAGIC_NUM 52571214
#endif
    if (*magic != MAGIC_NUM) {
        bug("Attempt to recyle invalid memory of size %d.", sMem);
        bug((char *)pMem + sizeof(*magic), 0);
        return;
    }

    *magic = 0;
    sMem += sizeof(*magic);
#endif

    for (iList = 0; iList < MAX_MEM_LIST; iList++)
        if (sMem <= rgSizeList[iList])
            break;

    if (iList == MAX_MEM_LIST) {
        bug("Free_mem: size %d too large.", sMem);
        exit(EXIT_FAILURE);
    }

    *((void **)pMem) = rgFreeList[iList];
    rgFreeList[iList] = pMem;

    return;
}

The bug message is

Attempt to recycle invalid memory of size 24.

Solution

  • This code is part of a set of memory management routines. When a client calls an allocation routine to allocate n bytes, the routine allocates n+s bytes, where s is the number of bytes in an int, likely 4. Let p be the address (in bytes) of the allocated memory. The allocation routine stores MAGIC_NUM at the address p and then returns the address p+s to the client.

    When a client calls free_mem to free memory, should provide that address it was given, p+s. free_mem subtracts s to calculate p and then inspects the memory at p to see if MAGIC_NUM is there. If it is not there, it knows that either the client provided an incorrect address or some code incorrectly overwrote the MAGIC_NUM that the allocation routine stored there. Either of these indictes an error in the program, so free_mem declares an error when MAGIC_NUM is not in the expected location.