3

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?

4

4 回答 4

7

在实践中是一样的。但是,它为您提供了一个重要功能。

假设您正在从网络接收一些数据,并且协议有一个字段,该字段指定数组将包含多少个元素,这些元素将发送给您。你做这样的事情:

uint32_t n = read_number_of_array_elements_from_network(conn);
struct element *el = malloc(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将检查该乘法中的溢出,并防止这种攻击(这种错误很常见)。

于 2013-09-26T07:22:59.940 回答
2

这是相同的。分配将元素数量乘以一个元素的大小来分配大小。

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

于 2013-09-26T06:52:31.163 回答
1

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

于 2013-09-26T06:53:35.293 回答
0

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

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

我所说的大小是指分配的每个元素。

于 2013-09-26T06:52:13.377 回答