calloc(10,4)和calloc(1,40)有什么区别?

时间:2013-09-26 06:48:46

标签: c calloc

calloc(10,4)和calloc(1,40)有什么区别?

我看到了这种行为:

Thing** things = (Thing**)calloc(1, 10 * sizeof(Thing*));
// things[0] != 0

Thing** things = (Thing**)calloc(10, sizeof(Thing*));
// things[0] == 0

我想了解原因。编辑:失去理智是为什么,现在两者似乎都导致零...至少让问题变得有趣,为什么calloc只需要一个参数,比如malloc?

5 个答案:

答案 0 :(得分:3)

在实践中它是一样的。但是这给你带来了一个重要的特征。

假设您正在从网络接收一些数据,并且协议有一个字段,用于指定将发送给您的阵列将包含多少元素。你做了类似的事情:

uint32_t n = read_number_of_array_elements_from_network(conn);
struct element *el = calloc(1, n * sizeof(*el));
if (el == NULL)
    return -1;
read_array_elements_from_network(conn, el, n);
这看起来无害,不是吗?好吧,不是那么快。连接的另一面是邪恶的,实际上发送了一个非常大的数字作为元素的数量,以便乘法包装。假设sizeof(*el)为4,n2^30+1。乘法2^30+1 * 4换行,结果变为4,这是你在告诉你的函数读取2 ^ 30 + 1个元素时分配的内容。 read_array_elements_from_network函数将快速溢出已分配的数组。

calloc的任何体面实现都会检查该乘法中的溢出并防止这种攻击(此错误非常常见)。

答案 1 :(得分:1)

calloc(10,4)将分配10个不包含大小为4的元素,而calloc(1,40)将分配一个大小为40的元素。

参考:http://www.tutorialspoint.com/c_standard_library/c_function_calloc.htm

按大小我的意思是分配的每个元素。

答案 2 :(得分:1)

它是一样的。分配的元素数量乘以一个元素的大小来分配大小。

没关系,因为它将是一个街区。

答案 3 :(得分:0)

它实际上是相同的,因为分配块是连续的。它分配number_of_elements * size_of_element,因此10个大小为4的元素或大小为40的1个元素最终都会分配40个字节。

答案 4 :(得分:0)

我认为为什么calloc有两个参数的答案是我们程序员可以活得更久,更容易编写代码或读取代码。很多事情都有这个解释:)