报价:
测试 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]不正确并且是内存泄漏,对不对?
问题的第二部分 - 我认为根据其名称的afree函数是删除保存在数组中特定位置的值。但是我可以看到它只是将“记录头”移动到阵列左侧的几个位置? 保存在那里的数据保持不变。
答案 0 :(得分: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
的{{1}}非常相似的函数,它在分配请求的内存块后将其全部初始化为零。
答案 1 :(得分:2)
关于问题的第二部分:afree()
或C
库free()
等内存管理功能通常零或清除内存。他们只是让它可以重复使用。这很好,因为您不支付性能成本。不幸的是,它可以掩盖错误,例如使用你不再拥有的内存。
出于安全原因调用free()
或协助调试时,某些堆管理器可能会将内存归零或使用特殊值填充它。标准不要求这样做,您必须专门启用此行为。