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.
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.