这段代码如何准确地知道pMem将始终是MAGIC_NUM的值?

问题描述 投票:0回答:1

我正在开发旧版 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 的无效内存。
c pointers memory memory-address
1个回答
0
投票

此代码是一组内存管理例程的一部分。当客户端调用分配例程来分配 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
会声明错误。

© www.soinside.com 2019 - 2024. All rights reserved.