【问题标题】:Why calloc takes two arguments while malloc only one?为什么 calloc 有两个参数,而 malloc 只有一个?
【发布时间】:2011-09-24 01:41:41
【问题描述】:

IMO 一个就够了,为什么calloc 需要将其拆分为两个参数?

【问题讨论】:

  • 因为一些程序员以这种方式创建了它,因此它永远存在......
  • 如果你不喜欢,#define calloc(x) (calloc)(x, 1) 应该可以。
  • @Chris 使用预处理器重新定义 malloc 或系列似乎是一个非常糟糕的主意(可能除了调试内存分配)。
  • 因为 calloc() 需要两个参数;一个定义元素的数量,一个定义元素的大小。顺便说一句, calloc() 将所有分配的内存清除为零。为什么会出现这个问题?
  • @peachykeen - 是的。从技术上讲,它在标准中是 UB,尽管在实践中不工作会很疯狂。也就是说,我的评论并不是真正的好的建议。

标签: c calloc


【解决方案1】:

我猜这可能是历史,并且早于 C 有函数原型的时代。在这些没有原型的时候,参数基本上必须是inttypedef size_t 可能还没有被发明出来。但是INTMAX 是您可以使用malloc 分配的最大块,将其分成两部分只会为您提供更大的灵活性并允许您分配非常大的数组。即使在那个时候,也有一些方法可以从系统中获取默认归零的大页面,因此calloc 的效率问题比malloc 的问题要小。

如今,有了 size_t 和手头的函数原型,这只是日常提醒 C 的丰富历史。

【讨论】:

  • 这根本不能回答问题。所用整数类型的宽度与本题完全无关。
  • @Jeff,你能解释一下吗?我并不是说今天使用的整数类型的宽度与它有什么关系。我是说在创建界面时它可能是个问题。
  • 我反对它用于“非常大的数组”的建议。使用两个参数代替一个参数是糟糕的 API 设计。以及为什么有人想要calloc 一个他们不能随后随意realloc 的指针,或者他们无法使用的指针,例如memset 还是 memcpy?随意对我的迂腐感到恼火,但有理由说 sizeof() 返回无符号并分配数组稍微大于INT_MAX
  • 此外,早期的 C (K&R) 有原型 - 非int 参数不需要它们。并且long int 存在,因此即使size_t 还没有出现,“大于int”的问题也有解决方案。
  • @Jeff,AFAIR 与int 不同类型的旧式 K&R 参数规范不提供原型。这些是在 C89 中引入的。对于 mallocrealloc 的不一致,您可能是对的,这是一个奇怪的界面选择。但不幸的是,这是为数不多的事情之一,我们现在坚持下去。
【解决方案2】:

参数名称记录得很好:

void *malloc(size_t size);
void *calloc(size_t nelem, size_t elsize);

后一种形式允许通过提供元素数量和元素大小来整齐地分配数组。 malloc 可以通过乘法来实现相同的行为。

但是,calloc 也将分配的内存初始化为 0。malloc 不进行初始化,因此该值未定义。 malloc理论上可以更快,因为没有设置所有的内存;这只可能会在大量时注意到。

this question中,建议calloc是clear-alloc,malloc是mem-alloc。

【讨论】:

  • 两个参数的另一个好处是可能会进行溢出检查,这对于malloc 来说通常很困难(而且很少完成)(尽管如果您分配的对象大小可能会溢出,您可能会这样做错误)。
  • @Chris:也许我们需要一个 cccalloc,它接受 6 个参数并分配 a*b + c*d + e*f 字节并对所有子表达式进行溢出检查... ;-)
  • 我认为这不是问题的答案。这并不询问这些是如何工作的(那么它只是一个重复的并且应该被关闭)。它要求将论点一分为二的原因,而不是像malloc那样只有一个总大小。
  • @Jens:他们做不同的事情,尤其是calloc 清除内存。这至少是答案的一部分。
  • @peachykeen,不,他们做不同的事情这一事实与一个需要一个参数而另一个需要两个参数这一事实无关。两者都使用它们的参数来确定要分配的内存的总大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 2017-11-24
  • 1970-01-01
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多