malloc和calloc为什么最终有不同的参数形式?

22

可能是重复问题:
为什么calloc需要两个参数,而malloc只需要一个参数?

有很多资源描述了malloccalloc之间功能差异的区别,但我找不到一个能够描述这些函数签名差异背后历史的资源:

   void *calloc(size_t nmemb, size_t size);
   void *malloc(size_t size);
当然,前者中的是每个成员的大小。也许这个想法是,通过操作系统可以懒惰地实现对页面大小的倍数成员大小 ?

非常相关:https://dev59.com/OFvUa4cB1Zd3GeqPu5bA - user142019
2
没有引用,所以只是一个评论——calloc的签名更可用,因为一个恰当的实现会在乘法溢出时检查,减轻调用者的责任。我怀疑有两种解释:(1)malloc先出现了,只是一种兼容性问题,(2)calloc预计会因为零清除而变慢,有人认为malloc中的乘法和溢出检查应该被省略以提高速度。 - Steve Jessop
2
我觉得很奇怪,一个问题可以被关闭为一个比较不具体的问题的完全重复,而且没有令人满意(或被接受的)答案 -- 我想知道这两个标记是如何历史上产生的。 - cdleary
1个回答

1

这在C规范中使用的语言上有些开放性解释。

这里使用的语言似乎非常谨慎 - malloc在第7.20.3.3节中定义为:

malloc函数分配一个大小由size指定且值不确定的对象的空间。

早期,对象在第3.14节中被定义为:

执行环境中的数据存储区域,其内容可以表示值

另一方面,calloc在7.20.3.1中定义为:

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

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

那么下一个问题是...为什么需要区分对象数组的空间和一个大对象的空间呢?

从程序员的角度来看,这两个函数调用只是在请求不同的东西。一个是请求分配一大块内存 - 我会处理它。另一个是说 - 我想要一个大小为n的这种类型的数组,给我一些可以用于此数组的内存,并将其清零 - 因为在大多数实现中,我可以对清零的内存做出良好的假设。
你试图将其用作malloc +清零的事实,在我阅读规范时,是对该函数目的的误解。
它们最终具有不同的签名,因为它们执行不同的操作。
一些有趣的想法...一个简单的malloc实现可能看起来像这样:
#define malloc(x) (calloc(1, x))

有趣的是,如果我的NULL指针表示没有被清零,那么calloc不会返回一个由NULL指针组成的数组。更好的是,如果我设计了一个整数表示,在其中清零的内存不是((int)0),那么calloc不会返回一个由0组成的数组。


所以你的意思是 calloc 返回一个初始化对象的数组(尽管在所有实现中,全零比特并不保证是所有类型的有效对象,但这至少是一种合理的初始化尝试),而 malloc 返回一个对象或数组的未初始化原始内存? - Steve Jessop
1
关于您的有趣笔记 - 您实际上可以设计一种实现方式,其中所有位为零都是除 charsigned/unsigned char 之外的每种类型的陷阱表示,从而使 calloc 几乎无用。作为推论,在严格符合规范的程序中,calloc 几乎无用,它的第二个参数在严格符合规范的程序中完全无用,因为它只对大小为1的类型有用。 - Steve Jessop
2
对于整数类型,全零比特始终是0的表示(也许不是唯一的表示)。这在C90或C99 ISO标准中没有说明,但它已经被添加到其中一个技术勘误表中(请参见n1256.pdf)。大概委员会觉得可以添加这个要求,因为所有现有的实现都已经满足了它。对于浮点数或指针类型,没有这样的保证。 - Keith Thompson
1
@KeithThompson:malloc(sizeof(double))是否保证返回一个有效对齐的*doublecalloc(sizeof(double),1)呢(与calloc(1,sizeof(double))不同)?虽然我会对任何系统在内存分配时不能始终满足最长类型所需的要求感到惊讶,但我认为这样的系统可能并不一定被禁止。 - supercat
@supercat:malloc()calloc()都保证返回适合任何类型的指针对齐。请参阅N1570 7.22.3(N1570是2011年ISO C标准的最新草案)。 - Keith Thompson
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接