K& R第5.4章:有关堆栈通过的问题

时间:2014-12-18 03:38:37

标签: c kernighan-and-ritchie

我正在使用" C编程语言(第2版)"我发现了一段关于记忆分配的文章,我无法理解:

参考本书对函数alloc(n)和afree(p)的内存分配的基本实现

  

C在解决算术的方法上是一致的和规则的;它集成指针,数组和地址算法是该语言的优势之一。让我们通过编写一个基本的存储分配器来说明。有两个例程。第一个,alloc(n),返回一个指向n个连续字符位置的指针,alloc的调用者可以使用它来存储字符。第二个,afree(p),释放由此获得的存储,以便以后可以重复使用。惯例是“基本的”''因为对afree的调用必须以与alloc上的调用相反的顺序进行。也就是说,由alloc和afree管理的存储是堆栈,或者是后进先出。标准库提供了类似的函数,称为malloc和free,没有这样的限制;

我所理解的问题是,当这段经文表明惯例是“不成熟的”时。因为对afree的调用必须以与alloc上的调用相反的顺序进行。这是否意味着在使用函数alloc之前必须首先调用函数afree?我理解堆栈数据结构的行为,但我不确定它的上下文是否说明函数调用"必须以相反的顺序进行#34;。

此外,该段的最后一句说明了malloc并且没有这样的限制。他们指的是什么限制?

4 个答案:

答案 0 :(得分:4)

我认为一个例子可以最好地解释这一点。

如果我拨打电话:

a = alloc(10);
b = alloc(10);
c = alloc(10);

我必须按此顺序致电afree:

afree(c);
afree(b);
afree(a);

这是基本的实施。在C语言中,您不需要以与调用malloc相反的顺序调用free。您可以多次使用malloc,然后再免费使用。

答案 1 :(得分:2)

这意味着如果你打电话:

p1 = alloc(n1);
p2 = alloc(n2);

你必须致电:

afree(p2);
afree(p1);

此限制(调用的强制顺序)在malloc和free中不存在(即使用malloc和free,您可以按任何顺序分配/释放)。

为什么会出现这种情况是因为alloc在堆栈中保存了分配的大小,而不是位置,所以基本上这些函数的作用是:

alloc - 分配n个字节。将n推入堆栈并返回指向已分配内存的指针 afree - 来自堆栈的弹出数字和自由表示从作为函数参数传递的指针位置开始的内存字节数。

如果你不打电话给他们,那么就会发生混乱。

答案 2 :(得分:0)

他们声称他们的自定义 allocafree例程是“基本的”,因为在他们的实现中,所有afree调用都必须反过来所有alloc来电的顺序。

这是限制,因为它们的例程是“基本的”(并且可能使用简单的堆栈而不是更复杂的记录保存方法实现)。

另一方面,实际的库例程mallocfree “基本”和限制 - free必须按照所有malloc来电的相反顺序拨打来电。

答案 3 :(得分:0)

所提到的限制是对afree的调用必须以与alloc调用相反的顺序进行。

malloc并免费使用一个叫做'堆'的巨大区域。

初始调用中的malloc创建了两个链接列表

第一个是堆中所有未分配的空间。

第二个是堆上所有已分配的空间。

首先,未分配链表上的第一个条目全部在包含所有堆的单个条目中。

分配的清单为空。

详细说明,每次分配(通过malloc)

1)在分配的列表中添加一个条目,指示调用者请求的大小 以及它在堆中的位置

2)将未分配的列表更改为仅显示当前未分配的堆的部分。

3)返回指向(新)分配列表的指针

free并不真正关心其被称为

的顺序

free获取传递给它的指针,在分配的链表中找到该条目

从已分配的链接列表中删除该条目

将该条目放入未分配的链表

尝试将来自未分配链表的相邻委托合并到 未分配链表中的单个条目。 (垃圾收集的一种形式)