为什么要calloc采用两个参数而不是一个malloc?
具体来说,由于以下表达式之间没有区别(或存在?):
calloc (a, b);
calloc (b, a);
calloc (a * b, 1);
calloc (1, a * b);
为什么不接受要分配的总字节数?这个界面背后的理由是什么?为什么这不适用于malloc?
我听到两个[互斥的]解释为什么它有两个论点:
calloc负责检查乘法溢出.如果请求的块的总大小太大(如溢出size_t),则calloc返回空指针以指示失败.随着malloc你必须注意溢出自己,很多人根本忘记做.(虽然标准库的历史知道calloc忽略溢出的实现的例子,因此工作不正确).
calloc实际上允许一个人分配比类型范围更大的内存块size_t,即calloc可能能够执行其参数的正确非溢出大乘法并分配结果大小的块.出于这个原因,由于calloc使用了两个类型的参数size_t,它可以分配比malloc以往更大的块(因为malloc只接受一个类型的参数size_t).
我一直认为第一个解释是正确的.但是,在阅读了这里的一些帖子后,我有疑虑.
我相信 malloc 保证返回一个根据最粗略的要求对齐的内存区域,该要求与第二个参数指示的大小兼容。例如,如果系统要求 2 和 4 字节整数对齐,并且第二个参数为 10,则返回的指针必须在双字节边界上对齐;如果第二个参数为 12,则指针将在四字节边界上对齐。我怀疑实际上许多系统会将所有返回的指针对齐到可能需要的最大边界,无论大小如何,但我认为除了 calloc 之外不需要它。
calloc(x,y)相当于malloc(x*y)
但calloc做额外的(将值设置为 0)memset(block, 0, x*y)
此函数仅用于以漂亮的方式传递元素的大小和元素的数量,当在 malloc 中时,您必须乘以这些值以获得所需的字节数,此函数也会在乘法中检查整数溢出。
例如,如果您想要为 12 个整数分配内存,并且想要对这些整数执行某些操作,并且必须将其值设置为 0,请使用calloc(12, sizeof(int))
但是,如果您想分配一些内存块(256 字节)以便将来将某个字符串复制到其中,那么这memset对您来说不可用,那么更好的使用是malloc(sizeof(char) * 256)或者例如malloc(sizeof(wchar_t) * 256)
void *
calloc (size_t nmemb, size_t lsize)
{
  void *ptr;
  struct __meminfo *info;
  size_t size = lsize * nmemb;
  /* if size overflow occurs, then set errno to ENOMEM and return NULL */
  if (nmemb && lsize != (size / nmemb))
    {
      set_errno (ENOMEM);
      return NULL;
    }
  /* allocate memory */
  ptr = malloc (size);
  /* get pointer to info part of chunk */
  info = __mem2info (ptr);
  /* fill memory with zeros and set __MEM_CALLOC flag */
  memset (ptr, 0, info->size);
  info->flags |= __MEM_CALLOC;
  return ptr;                   /* happy end */
}