Menu
Coddy logo textTech

Выделение памяти с помощью calloc()

Часть раздела Logic & Flow путешествия по C на Coddy — урок 36 из 63.

В то время как malloc() является наиболее распространенной функцией для динамического выделения памяти, C предоставляет еще одну полезную альтернативу: calloc(). Функция calloc(), название которой расшифровывается как «contiguous allocation» (непрерывное выделение), предлагает удобный способ выделения памяти для массивов с важным дополнительным преимуществом.

В отличие от malloc(), которая принимает один аргумент (общее количество байт), calloc() принимает два аргумента: количество элементов, которые вы хотите выделить, и размер каждого элемента. Это делает её особенно интуитивно понятной при работе с массивами. Например:

#include <stdlib.h>

// Выделение памяти для 5 целых чисел с помощью calloc()
int *arr = (int*)calloc(5, sizeof(int));

// Это эквивалентно: malloc(5 * sizeof(int))

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

Как и malloc(), calloc() возвращает указатель на выделенную память или NULL, если выделение памяти завершилось неудачей, поэтому вам всегда следует проверять результат выделения и не забывать free() память, когда вы закончите её использовать.

challenge icon

Задание

Легко

Напишите программу на языке C, которая демонстрирует использование calloc() для динамического выделения памяти с автоматической инициализацией нулями. Ваша программа должна:

  1. Считать целое число size от пользователя, представляющее количество целых чисел для выделения памяти
  2. Использовать calloc() для динамического выделения памяти под массив из size целых чисел
  3. Проверить, было ли выделение памяти успешным — если оно не удалось, вывести Memory allocation failed! и завершить программу
  4. Если выделение памяти прошло успешно, вывести Memory allocated and initialized to zero!
  5. Вывести все начальные значения в массиве, чтобы продемонстрировать, что они равны нулю, в формате: Initial values: [value1] [value2] [value3] ...
  6. Считать size целых чисел от пользователя и сохранить их в выделенном массиве
  7. Вывести все обновленные значения в формате: Updated values: [value1] [value2] [value3] ...
  8. Вычислить и вывести сумму всех значений в формате: Sum: [value]
  9. Использовать free() для освобождения памяти
  10. Вывести Memory freed! для подтверждения очистки

Не забудьте включить заголовочный файл <stdlib.h> для использования calloc() и free(). Эта задача демонстрирует ключевое преимущество calloc() перед malloc(): автоматическую инициализацию всей выделенной памяти нулями.

Например, если входные данные:

3
10 20 30

Ваш вывод должен быть:

Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!

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

Шпаргалка

Функция calloc() обеспечивает динамическое выделение памяти с автоматической инициализацией нулями.

Синтаксис:

void* calloc(size_t num_elements, size_t element_size);

Основные отличия от malloc():

  • Принимает два аргумента: количество элементов и размер каждого элемента
  • Автоматически инициализирует всю выделенную память нулями
  • Более интуитивно понятна для выделения памяти под массивы

Пример использования:

#include <stdlib.h>

// Выделение памяти для 5 целых чисел с помощью calloc()
int *arr = (int*)calloc(5, sizeof(int));

// Это эквивалентно: malloc(5 * sizeof(int))
// Но все значения гарантированно равны 0

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

Попробуйте сами

#include <stdio.h>
#include <stdlib.h>

int main() {
    int size;
    
    // Считать размер массива
    scanf("%d", &size);
    
    // TODO: Напишите ваш код ниже
    // Используйте calloc() для выделения памяти под массив
    // Проверьте, было ли выделение памяти успешным
    // Выведите начальные значения (должны быть нулевыми)
    // Считайте и сохраните входные значения
    // Выведите обновленные значения
    // Вычислите и выведите сумму
    // Освободите выделенную память
    
    return 0;
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Logic & Flow