calloc是否将整个分配归零?

calloc是否将整个分配归零?,c,malloc,calloc,C,Malloc,Calloc,C中的calloc函数用于分配调零内存,该内存至少能够容纳指定大小的请求数量的元素。实际上,大多数内存分配器可能会分配更大的块,以提高效率和最小化碎片。此类系统中分配的实际可用块大小通常可通过特殊功能发现,即\u msize或malloc\u可用块大小 calloc将确保整个可用块归零,还是仅将分配的请求计数*大小部分归零?这取决于实现。该标准不要求其归零超过请求的内存大小 说: 简介 #include <stdlib.h> void *calloc(size_t nmemb, si

C中的
calloc
函数用于分配调零内存,该内存至少能够容纳指定大小的请求数量的元素。实际上,大多数内存分配器可能会分配更大的块,以提高效率和最小化碎片。此类系统中分配的实际可用块大小通常可通过特殊功能发现,即
\u msize
malloc\u可用块大小


calloc将确保整个可用块归零,还是仅将分配的请求计数*大小部分归零?

这取决于实现。该标准不要求其归零超过请求的内存大小

说:

简介

#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);

它只会将您请求的内存归零。其他实现可能会有所不同。

只保证将请求的分配归零


你永远不应该依赖过度分配。

简短的回答:没有更多的信息,这是不可能说的,但我不会指望它

详细回答:

如果您请求N个字节,C标准保证(除非失败)
calloc
将为您提供N个字节,并且它们都将为0。就C标准而言,这就是我们所能说的

如果你有一个C库,它(a)有时给你超过N个字节,(b)给你一个明确定义的方法来找出有多少个字节,并且(C)保证允许你使用这些额外的字节,我们显然不能说这些字节是否保证为0。C标准没有告诉我们,我们也不知道您使用的是什么C库,或者它的特殊保证是什么


由于您的C库可能会为您提供(a)、(b)和(C),因此您必须查阅该库的文档、源代码和/或作者,以回答以下问题(d)是否有任何额外内存保证为0?这个问题没有通用的、非特定于图书馆的答案。

为什么这很重要?您只能使用请求的大小,剩余的大小(如果有的话)无论如何对您都不可用。@SouravGhosh:OP询问的是一个扩展,其中C实现提供了
malloc\u-usable\u-size
或类似的函数来报告内存的可用大小,可能比请求的大。在这种实现中,报告为可用的量是可用的,并且使用它的行为是被定义的。请阅读
malloc\u-available\u-size
:此函数的主要用途是调试和内省。@AndrewHenle:您需要的和您可以有效使用的可能是不同的东西。例如,进程可能会为缓存目的分配空间。为此,它可能会要求一些合理的金额,以帮助它有效地提供服务。如果C实现提供了更多的空间,那么使用额外的空间可以进一步提高性能,而不必付出任何代价。@Andrew Henle:你错了。请求的大小不是唯一可用的内存。在提供确定分配可用大小方法的编译器/lib上,程序可以安全地使用所有返回的大小。甚至不询问用例就称某些东西为“完全脑损伤”,这显然是不礼貌的。假设预先知道所需的分配大小肯定是错误的:许多数据结构在空间不足时依赖于调整缓冲区的大小,而使用整个分配可以通过避免调用realloc来提高性能。您是如何知道这一点的?OP询问的是一个C实现,在该实现中,如果实际分配了更多内存,则该实现支持使用比请求更多的内存,正如该实现提供的函数所报告的那样。该C实现还可能清除
calloc
分配的所有内存,而不仅仅是请求的数量。这个问题需要通过参考C实现的文档来回答,而不是C标准。@EricPostpischil作为一个例子,GNU libc只保证将请求的分配归零,这可以通过检查其源代码来确定。@IanAbbott这是正确的检查,但是,它显然不能给您提供与文档中的明确声明相同的长期保证。(而且,可以肯定的是,即使文件中的明确声明也可能在以后的版本中进行修改。)@SteveSummit我认为在这种情况下,没有必要做出明确的声明。
malloc\u userable\u size
的文档已经阻止程序员尝试利用块中包含的任何额外空间。@IanAbbott我的意思是,一般来说,通过偷看源代码并说“它是有保证的…”来回答有关未记录功能的问题是一个危险的提议。:-)
PTR memset (PTR dest, register int val, register size_t len) {
  register unsigned char *ptr = (unsigned char*)dest;
  while (len-- > 0)
    *ptr++ = val;
  return dest;
}

void bzero (void *to, size_t count) {
  memset (to, 0, count);
}

PTR calloc (size_t nelem, size_t elsize) {
  register PTR ptr;  
  if (nelem == 0 || elsize == 0)
    nelem = elsize = 1;

  ptr = malloc (nelem * elsize);
  if (ptr) bzero (ptr, nelem * elsize);

  return ptr;
}