2011-09-28 45 views
20

可能重复:
Why calloc takes two arguments while malloc only one?malloc和calloc如何以不同的签名结束?

很多描述malloccalloc之间在功能上的差异资源,但我不能很容易地找到一个描述背后的历史不同的功能签名:

void *calloc(size_t nmemb, size_t size); 
    void *malloc(size_t size); 

当然,前者中的size是每个成员的大小。也许这个想法是多页面大小的成员大小callocs可以通过OS懒懒地完成?

(我可以弥补的原因,以及未来的家伙 - 没有公认的答案没有援引消息人士:-)

+0

极其相关:http://stackoverflow.com/q/7536413/142019 – 2011-09-28 09:47:21

+1

没有引用,所以只是一个注释 - 'calloc'签名更加实用,因为一个适当的实现检查乘法溢出,减轻来电者的责任。我怀疑以下两种解释之一:(1)'malloc'出现在第一位,这只是一个兼容性问题,(2)'calloc'由于归零会变慢,有人认为乘法和溢出检查在'malloc'中应该省略速度。 –

+0

我觉得奇怪的是,一个问题可以被关闭为一个没有满足(或接受)答案的不太具体的问题的完全重复 - 我想知道两个签名是如何在历史上出现的。 – cdleary

回答

1

这是在C说明书中使用的语言的解释有点开放。

这里的语言似乎很慎重选择 - malloc的是在第7.20.3.3定义:

malloc函数的对象由size指定的大小为 ,其价值是不确定的分配空间。

早些时候一个目的是在3.14节定义为:数据存储在执行环境中的

区域,所述 其内容可以代表的数值,另一方面

释放calloc在7.20.3.1中定义为:

calloc函数为数组分配空间nmemb对象, ,每个大小都是大小。该空间初始化为所有位 零。

这应该很明显。 calloc和malloc的区别在于calloc为n个概念对象的数组分配内存,尽管在实践中这与为malloc分配1个概念对象(n * size)空间的malloc没有区别。

所以下一个问题是......对于一个大对象的空间对象数组和空间的区分需要什么?

从程序员的角度来看,这两个函数调用只是要求不同的东西。一个是要求分配一大块内存 - 我会处理它。另一种说法是 - 我想要一个n大小的数组,给我一些我可以用于这个数组的内存,并将它归零 - 因为在大多数实现中,我可以对内存归零的含义做出很好的假设。

您试图将它用作malloc +清零的事实是,通过阅读规范,对函数的用途产生误解。

他们结束了不同的签名,因为他们做了不同的事情。


一些可爱的一面的想法...一个不重要的malloc实现可以是这样的:

#define malloc(x) (calloc(1, x)) 

这也是有趣的注意,如果我的NULL指针表示不归零,然后释放calloc不会返回一个NULL指针数组。更好的是,如果我设计一个整数表达式,其中归零内存不是((int)0),calloc不会返回给我一个0的数组。

+0

所以你基本上说'calloc'返回一个初始化对象的数组(所有位都不能保证是所有实现中的所有类型的有效对象,这至少是初始化的合理尝试),而'malloc'返回一个对象或数组的原始未初始化内存? –

+0

关于你的有趣笔记 - 你实际上可以设计一个实现,其中all-bits-zero是除char和signed/unsigned char之外的每种类型的陷阱表示,呈现calloc几乎是无用的。作为一个推论,'calloc'在严格符合程序中几乎是无用的,而且它的第二个参数在严格符合程序中是完全没有用的,因为它唯一有用的类型的大小为1. –

+0

@Steve Jessop:只要陷阱表示不成问题因为你不评估它们 - 你可以在严格符合的程序中覆盖它们。 – caf