Когда я должен использовать calloc поверх malloc

#c #pointers #dynamic-memory-allocation

#c #указатели #динамическое выделение памяти

Вопрос:

Это из руководства Beej по C «Недостатком использования calloc () является то, что для очистки памяти требуется время, и в большинстве случаев вам не нужно ее очищать, поскольку вы все равно будете просто писать поверх нее. Но если вы когда-нибудь обнаружите, что malloc () вводит блок, а затем сразу после этого обнуляет память, вы можете использовать calloc (), чтобы сделать это за один вызов.»

итак, каков потенциальный сценарий, когда я захочу очистить память до нуля.

Ответ №1:

Когда функция, которой вы передаете буфер, указывает в своей документации, что буфер должен быть заполнен нулем. Вы также всегда можете обнулить память для безопасности; на самом деле это не занимает так много времени, если буферы не действительно огромны. Выделение памяти само по себе является потенциально дорогостоящей частью операции.

Ответ №2:

Один из сценариев заключается в том, что вы выделяете массив целых чисел (скажем, в качестве аккумуляторов или переменных счетчика) и хотите, чтобы каждый элемент в массиве начинался с 0.

Ответ №3:

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

 1> malloc that structure and memset it with 0 before using that structure 
  

или

 2> calloc that structure  
  

Примечание: некоторые продвинутые программы управления памятью с malloc также сбрасывают память на 0

Ответ №4:

Есть много случаев, когда вы можете захотеть, чтобы память была обнулена!

Несколько примеров:

  • Выделение памяти для размещения структуры, в которой вы хотите, чтобы все элементы были инициализированы нулем
  • Выделение памяти для массива символов, в который вы позже собираетесь записать некоторое количество символов, а затем обработать как строку, завершающуюся нулем
  • Выделение памяти для массива указателей, которые вы хотите инициализировать в NULL

Комментарии:

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

Ответ №5:

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

(по аналогичным причинам при отладке программы на C или C в Linux я обычно делаю это, echo 0 > /proc/sys/kernel/randomize_va_space чтобы mmap поведение было более воспроизводимым).

И если ваша программа не выделяет огромные блоки (т. Е. десятки мегабайт), время, затрачиваемое внутри malloc, намного больше, чем время на его обнуление.