我正在开发旧版 MUD 代码库,并且我一直在这段代码中收到错误消息。我试图理解它,但我也想知道它是如何工作的?地址不是总是随机的吗?感谢您的帮助!
/*
* 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;
}
错误消息是
尝试回收大小为 24 的无效内存。
此代码是一组内存管理例程的一部分。当客户端调用分配例程来分配 n 字节时,该例程会分配 n+s 字节,其中 s 是
int
中的字节数,可能为 4。令 p 为分配的内存的地址(以字节为单位)。分配例程将 MAGIC_NUM
存储在地址 p 处,然后将地址 p+s 返回给客户端。
当客户端调用
free_mem
释放内存时,应提供给定的地址,p+s。 free_mem
减去s来计算p,然后检查p处的内存以查看MAGIC_NUM
是否存在。如果不存在,则它知道客户端提供了不正确的地址,或者某些代码错误地覆盖了分配例程存储在那里的MAGIC_NUM
。其中任何一个都表明程序中存在错误,因此当 free_mem
不在预期位置时,MAGIC_NUM
会声明错误。