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?
答案 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,n
为2^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
有两个参数的答案是我们程序员可以活得更久,更容易编写代码或读取代码。很多事情都有这个解释:)