5

引述:

测试 if (allocbuf + ALLOCSIZE - allocp >= n) { 检查是否有足够的空间来满足对 n 个字符的请求。如果有,allocp 的新值最多会超出 allocbuf 的末尾。

它涉及的代码:

#define ALLOCSIZE 10000 /* size of available space */
static char allocbuf[ALLOCSIZE]; /* storage for alloc */
static char *allocp = allocbuf; /* next free position */

char *alloc(int n)
/* return pointer to n characters */
{
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        allocp += n;
        return allocp - n; /* old p */
    } else
/* not enough room */
        return 0;
}
void afree(char *p) /* free storage pointed to by p */
{
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE)
        allocp = p;
}

那么怎么能超出allocbuf中的最后一个位置呢?在我看来是 allocbuf[9999]

除此之外的任何东西,例如。allocbuf[10000] 不正确,是内存泄漏,对吗?


问题的第二部分 - 我虽然根据其名称的自由函数正在删除保存在数组中特定位置的值。但是,正如我所见,它只是将“记录头”移动到数组左侧的几个位置?保存在那里的数据保持不变。

4

2 回答 2

5

allocp应该总是指向最后一个空闲的内存位置,但是当没有可用的内存位置时,它将是allocbuf.

考虑缓冲区中只剩下一个内存单元的情况:allocp将指向allocbuffer[9999]因为这是最后一个空闲内存单元。现在,当您使函数调用alloc(1)测试时

allocbuf + ALLOCSIZE - allocp >= n

将返回 true ,因为您正在尝试分配一个char并且char只剩下一个。然后将分配最后一个内存位置。现在allocbuf - allocp == ALLOCSIZE和是一个超越结束的allocbuf。但在这种情况下,上述测试将始终返回 false,因此不会访问超出范围的内存allocbuf


关于您的问题afree:返回的内存的初始值malloc未定义。这意味着您永远不能对它做出任何假设,并且必须在使用前覆盖它。因此afree,不必删除与您假设相反的任何数据。将其简单地标记为不再使用并可供将来分配是完全可以的。

malloc附带说明一下,有一个与named非常相似的函数,calloc它在分配请求的内存块后将其全部初始化为零。

于 2012-08-14T15:03:00.487 回答
2

关于您问题的第二部分:像库这样afree()的内存管理功能通常不会清零或清除内存。他们只是让它可供重用。这很好,因为您无需支付性能成本。不幸的是,它可以掩盖错误,例如使用您不再拥有的内存。Cfree()

free()当您出于安全原因或协助调试时,某些堆管理器可能会将内存归零或使用特殊值填充它。这不是标准要求的,您必须专门启用此行为。

于 2012-08-14T15:32:20.010 回答