C - calloc () против malloc ()


person Kevin Meredith    schedule 10.08.2010    source источник
comment
Это кажется довольно очевидным. Какой вопрос?   -  person Starkey    schedule 10.08.2010
comment
Вы не понимаете, что такое мусорные значения?   -  person Albinoswordfish    schedule 10.08.2010
comment
Почему malloc () не инициализируется? Мне кажется, что calloc () следует использовать вместо malloc (), предполагая, что инициализация памяти является хорошей практикой.   -  person Kevin Meredith    schedule 10.08.2010
comment
Что, если бы вы захотели использовать эту память для чего-то другого, кроме нулей? Тогда вы зря потратили время на то, чтобы установить все значение в 0.   -  person Paul Tomblin    schedule 10.08.2010
comment
нет причин обнулять память, если вы инициализируете память для заполнения сразу после этого. например копирование строки в распределенную память, инициализация структуры с различными значениями и т. д.   -  person nos    schedule 10.08.2010
comment
Что значит инициализировать память до 0? Я заблудился.   -  person lmiguelvargasf    schedule 26.04.2016


Ответы (4)


С http://wiki.answers.com/Q/Is_it_better_to_use_malloc_or_calloc_to_allocate_memory

malloc() работает быстрее, поскольку calloc() инициализирует выделенную память, чтобы она содержала все нули. Поскольку вы обычно хотите использовать и инициализировать память самостоятельно, это дополнительное преимущество calloc() может не понадобиться.

person Edward Leno    schedule 10.08.2010
comment
Согласно этой недавней статье, это неправда. Он показывает, что каллок в основном работает быстрее и имеет ряд других преимуществ. vorpus.org/blog/why-does-calloc-exist - person eric.frederich; 06.12.2016
comment
Я согласен, calloc не только обычно быстрее в современной системе, но иногда и намного быстрее, и с его помощью можно избежать некоторых неприятных ошибок! Для встроенных файлов YMMV. - person John Lawrence Aspden; 17.09.2018

calloc инициализирует память перед ее использованием, но malloc нет.

См. эту ссылку:

Функция calloc () должна выделить неиспользуемое пространство для массива элементов nelem, размер каждого из которых в байтах равен elsize. Пространство должно быть инициализировано всеми битами 0.

С malloc, если вы хотите гарантировать тот же эффект, вам придется вызвать что-то вроде memset для сброса памяти, например

char* buffer = (char*)malloc(100);
memset(buffer,0,100);

calloc избавит вас от лишнего шага. Значение инициализации памяти состоит в том, что вы переводите переменную в известное состояние, а не в неизвестное. Поэтому, если вы проверяете переменную, скажем, элемент массива, на предмет ожидаемого значения, то, предварительно инициализировав переменную заранее, вы можете быть уверены, что проверяемое значение не является мусором. Другими словами, вы можете отличить мусор от допустимых значений.

Например, если вы просто оставляете мусор в переменной и проверяете какое-то значение, скажем 42, тогда у вас нет возможности узнать, действительно ли значение было установлено на 42 вашей программой, или это просто остаток мусора, потому что вы не инициализировал его.

person dcp    schedule 10.08.2010
comment
Спасибо. Какое значение имеет инициализация памяти? Почему malloc () не инициализируется? - person Kevin Meredith; 10.08.2010
comment
В большинстве случаев, как только вы выделяете память, вы собираетесь заполнить ее содержимое самостоятельно (например, присвоив значения всем элементам в массиве или всем полям в структуре). В этом случае вам не нужно обнулять память перед ее использованием, поэтому вы используете malloc. Если у вас есть особая потребность в обнулении памяти, вы можете использовать calloc. Это эквивалентно malloc, за которым следует memset, но может быть быстрее, потому что распределитель может с этим справиться. - person Tom Anderson; 10.08.2010
comment
Пример неверен, sizeof(buffer) равно sizeof(char *); он не будет инициализировать весь буфер обнулением. - person Praetorian; 10.08.2010
comment
Представьте, что вам выделили участок земли. Вы не знаете, где находится земля, вы не знаете, что находится на ней, все, что вам дают, - это правовой титул. Это то, что эффективно делает malloc - возвращает указатель на область памяти. Теперь calloc может быть похож на malloc, за исключением того, что совет гарантирует, что сначала все снесет с земли. Занимает намного больше времени и, следовательно, дороже, но вы знаете, что получаете. Твой выбор. - person PP.; 10.08.2010

calloc(...) в основном malloc + memset (если вы хотите 0 инициализировать память)

ptr = malloc(sizeof(struct fubar));
memset(ptr, 0, sizeof (struct fubar)); //here we could use some different value instead of 0 whereas calloc always 0 initialises.

Когда вы используете malloc для выделения некоторой памяти, предыдущее содержимое не очищается (т.е. не инициализируется). Вы можете получить случайные значения, которые были установлены при загрузке машины, или вы можете увидеть часть памяти, которая принадлежала ранее запущенным программам, но осталась не очищенной после выделения и выхода из программы.

calloc сам по себе медленнее, чем malloc, потому что вам нужно потратить некоторое время на очистку содержимого выделенной памяти. Так что, если вам просто нужно выделить немного памяти, а затем скопировать туда что-то, вы можете использовать malloc.

person plaes    schedule 10.08.2010
comment
не произносите malloc - person cat; 24.09.2016
comment
@cat, спасибо исправлено;) - person plaes; 26.09.2016

Это просто означает, что если вы выделяете память с помощью calloc (), все, что вы выделяете, равно 0. т.е. если вы выделили пространство для массива целых чисел, все они будут установлены в 0, тогда как с malloc () память там не будет никак не инициализируется.

Вы можете использовать calloc в ситуациях, когда вы в любом случае собираетесь сделать memset равным 0 для памяти.

person Shawn D.    schedule 10.08.2010