Есть ли какие-то преимущества в использовании calloc() вместо malloc() и memset()?

Мне было интересно, предпочтительнее ли calloc(), чем malloc, за которым следует memset. Последний представляется наиболее распространенным способом выделения и инициализации памяти.

поиск по коду github выдает множество calloc тестов и реализаций, но на первых страницах на самом деле нет кода, использующего calloc.

Кто-нибудь знает о каких-либо проектах/организациях, которые используют или рекомендуют использовать calloc, и при каких обстоятельствах это рекомендуется?

Из комментариев и ответов ниже, вот некоторые мысли, которые возникли до сих пор:

  • calloc(n, size) может предотвратить переполнение, которое возможно с malloc(n * size)

  • сочетание malloc и memset дает calloc возможность запросить страницу, которая, как известно, уже обнулена.

  • недостатком calloc является то, что объединенные шаги могут помешать другим оболочкам вокруг malloc.


person Kevin Cox    schedule 18.03.2013    source источник
comment
Никогда не знал, чтобы кто-нибудь использовал его, и я никогда не использовал его, несмотря на то, что знал о его существовании. Я не знаю почему, но это просто не похоже на C.   -  person Dave    schedule 18.03.2013
comment
Обратите внимание, что malloc(), за которым следует memset(), практически гарантированно будет медленнее, чем calloc().   -  person Dietrich Epp    schedule 18.03.2013
comment
Если вы будете искать на GitHub malloc, вы также найдете реализации и тестовый код, прежде чем найдете применение.   -  person Dietrich Epp    schedule 18.03.2013
comment
@DietrichEpp относительно вашего комментария о скорости malloc/memset vs calloc: я был бы удивлен, если бы в этом была правда при использовании оптимизирующего компилятора. Можете ли вы указать причину или показать ориентир? Все, о чем я могу думать, это лучшее кэширование, но malloc вообще не проходит через память.   -  person Dave    schedule 18.03.2013
comment
@Dave: это не имеет ничего общего с компилятором. Сам вызов функции выполняется быстрее. См. мой ответ на другой вопрос: stackoverflow. com/questions/2688466/ — разница в скорости может быть огромной, я замерил разницу в 1500 раз в одном бенчмарке.   -  person Dietrich Epp    schedule 18.03.2013
comment
@DietrichEpp: вау, достаточно честно. Я думаю, что с этого момента я буду использовать calloc, когда мне понадобится обнуленная память!   -  person Dave    schedule 18.03.2013
comment
@DietrichEpp Я нахожу использование malloc на второй странице. Я не говорю, что calloc не используется, но он появляется реже.   -  person Kevin Cox    schedule 18.03.2013
comment
@KevinCox: Не могли бы вы дать ссылку? Я вижу только код для тестирования malloc() на второй странице. И я уверен, что calloc() встречается реже, точно так же, как деление встречается реже, чем умножение, но вы не видите, чтобы люди спрашивали, почему мы не можем от него избавиться.   -  person Dietrich Epp    schedule 18.03.2013
comment
@DietrichEpp Похоже, мой процесс проверки был недостаточно хорош. Ты прав. Стоит отметить, что github предпочитает файлы с поисковым запросом в имени, что фактически делает этот простой тест бесполезным.   -  person Kevin Cox    schedule 18.03.2013
comment
Я голосую за повторное открытие этого, потому что 1) конструктивно изучить причины, лежащие в основе текущей практики, и 2) я считаю, что в операционных системах на самом деле существует разница между тем, что malloc/memset и calloc.   -  person Raymond Hettinger    schedule 08.08.2015
comment
Между ними есть еще одно различие: целочисленное переполнение. malloc(num * size) и calloc(num, size) ведут себя по-разному для больших чисел. Для получения дополнительной информации см. Ray Статья Лая Undeadly о целочисленных переполнениях. Также из-за этого OpenBSD создала reallocarray.   -  person Cristian Ciupitu    schedule 08.08.2015
comment
@RaymondHettinger, не мешало бы перефразировать вопрос, чтобы сделать его более подходящим для этого сайта.   -  person Cristian Ciupitu    schedule 08.08.2015


Ответы (1)


Ну, я использую calloc довольно часто в коде на C, так что я думаю, что это ответ. Я думаю, что немного необычный метод вызова (количество элементов и размер элемента) может сбить людей с толку. Однако еще одна причина, по которой вы можете увидеть не так много вызовов, как вы ожидаете, заключается в том, что многие более крупные проекты используют обертки вокруг malloc, calloc и им подобных, которые выполняют обработку ошибок (обычно завершая программу) при сбое выделения памяти. Таким образом, фактический код использует вместо этого xcalloc.

Одна из причин использования calloc вместо malloc плюс memset заключается в том, что calloc может быть более эффективным. Если библиотека C уже знает, что страница обнулена (возможно, она только что получила новую обнуленную память от ОС), ей не нужно явно обнулять ее.

person rra    schedule 18.03.2013