calloc的两个参数

为什么calloc采用两个参数而不是像malloc一样?

具体来说,由于以下表达式之间没有区别(或存在?):

 calloc (a, b); calloc (b, a); calloc (a * b, 1); calloc (1, a * b); 

为什么不接受要分配的总字节数? 这个界面背后的理由是什么? 为什么这不适用于malloc?

我听到两个[互斥的]解释为什么它有两个论点:

  1. calloc负责检查乘法上的溢出。 如果请求块的总大小太大(如overflows size_t ),则calloc返回空指针以指示失败。 使用malloc您必须自己注意溢出,许多人根本忘记这样做。 (虽然标准库的历史知道了忽略溢出的calloc实现的例子,因此工作不正确)。

  2. calloc实际上允许分配比size_t类型的范围更大的内存块,即calloc可能能够执行其参数的正确非溢出大乘法并分配结果大小的块。 出于这个原因,由于calloc使用两个类型为size_t参数,它可以分配比malloc更大的块(因为malloc只接受一个size_t类型的参数)。

我一直认为第一个解释是正确的。 然而,在阅读了这里的一些post后,我有疑虑。

我相信malloc可以保证返回一个内存区域,该区域根据与第二个参数指示的大小兼容的最粗糙的要求进行对齐。 例如,如果系统需要对齐2和4字节整数,并且第二个参数为10,则返回的指针必须在双字节边界上对齐; 如果第二个参数是12,则指针将在四字节边界上对齐。 我怀疑在实践中,许多系统会将所有返回的指针对齐到最大可能需要的边界,无论大小如何,但我不认为除了calloc之外它是必需的。

唯一值得注意的区别是calloc需要将分配的空间初始化为零,而malloc没有这样的保证。 否则,我想只是出于历史原因有两种不同的function。

一切都只是字节是一个相对较新的(即c / Unix时代)发明 – 在很多其他架构上的东西都是固定大小的记录。

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 */ }