malloc和calloc是如何以不同的签名结束的?

cdl*_*ary 20 c history std libc

可能重复:
为什么calloc接受两个参数而malloc只有一个?

很多资源描述了malloc和之间的功能差异calloc,但我不能轻易找到描述不同功能签名背后的历史的资源:

   void *calloc(size_t nmemb, size_t size);
   void *malloc(size_t size);
Run Code Online (Sandbox Code Playgroud)

当然,size前者是每个成员的大小.也许这个想法是可以通过操作系统懒散地完成多页面大小的成员大小的calloc?

(我可以弥补原因以及下一个人 - 没有引用来源没有接受的答案.:-)

Jam*_*lgh 1

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

这里的语言似乎是经过精心选择的 - malloc 在第 7.20.3.3 节中定义为:

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

早些时候,第 3.14 节中将对象定义为:

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

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

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

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

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

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

根据我对规范的阅读,您尝试将其用作 malloc + 归零这一事实是对该函数用途的误解。

他们最终得到了不同的签名,因为他们做了不同的事情。


一些可爱的侧面想法...一个简单的 malloc 实现可能如下所示:

#define malloc(x) (calloc(1, x))
Run Code Online (Sandbox Code Playgroud)

同样有趣的是,如果我的 NULL 指针表示未归零,则 calloc 将不会返回 NULL 指针数组。更好的是,如果我设计一个整数表示,其中归零内存不是 ((int)0),calloc 不会返回 0 数组。

  • 对于整数类型,全位零始终是 0 的表示形式(也许不是唯一的表示形式)。 C90 或 C99 ISO 标准中没有说明这一点,但在一份技术勘误表中添加了它(请参阅 n1256.1)。 pdf)。想必委员会可以随意添加这一要求,因为所有现有的实现都已经满足了它。对于浮点或指针类型没有这样的保证。 (2认同)