2013-09-26 6 views
3

В чем разница между calloc (10,4) и calloc (1,40)?В чем разница между 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

+1; Я сам это задался. Я хотел бы знать, будет ли это во всех случаях одинаковым; т.е. существует ли стандартный мандат? – Bathsheba

ответ

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 будет проверять переполнение в этом умножении и будет защищать от такого рода атак (эта ошибка очень распространена).

+0

+1 Переполнение было более очевидным в DOS 16-битных днях. – chux

1

calloc (10,4) не будет выделять 10 нет элементов, где размер будет 4, в то время как calloc (1,40) будет выделен один elment с размером 40.

Ссылка: http://www.tutorialspoint.com/c_standard_library/c_function_calloc.htm

По размеру i означает для каждого выделенного элемента.

1

Это то же самое. Распределение делает количество элементов раз по размеру одного элемента для распределения размера.

Не имеет значения, так как это будет один блок.

0

Это практически то же самое, что и блок выделения. Он выделяет number_of_elements * size_of_element, поэтому 10 элементов размером 4 или 1 элемента размера 40 оба заканчивают выделение 40 байтов.

0

Я думаю, что ответ, почему calloc имеет два аргумента, что мы программист может жить дольше, для легко писать код, или читать code.Many вещи есть это объяснить :)