Выделение памяти с помощью 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() память, когда вы закончите её использовать.
Задание
ЛегкоНапишите программу на языке C, которая демонстрирует использование calloc() для динамического выделения памяти с автоматической инициализацией нулями. Ваша программа должна:
- Считать целое число
sizeот пользователя, представляющее количество целых чисел для выделения памяти - Использовать
calloc()для динамического выделения памяти под массив изsizeцелых чисел - Проверить, было ли выделение памяти успешным — если оно не удалось, вывести
Memory allocation failed!и завершить программу - Если выделение памяти прошло успешно, вывести
Memory allocated and initialized to zero! - Вывести все начальные значения в массиве, чтобы продемонстрировать, что они равны нулю, в формате:
Initial values: [value1] [value2] [value3] ... - Считать
sizeцелых чисел от пользователя и сохранить их в выделенном массиве - Вывести все обновленные значения в формате:
Updated values: [value1] [value2] [value3] ... - Вычислить и вывести сумму всех значений в формате:
Sum: [value] - Использовать
free()для освобождения памяти - Вывести
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;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Основы указателей
Что такое указатель?Объявление указателейОператор взятия адреса (&)Оператор разыменования (*)Указатели NULLИтоги: Основы указателей4Проект: Простая текстовая утилита
Обзор проектаПодсчет символов2Указатели и массивы
Имена массивов как указателиЭлементы массива — указателиАрифметика указателейСравнение указателейИтоги: Обход массива через указатели5Указатели и функции
Передача по значениюПередача указателей в функцииИзменение переменных через указателиКлассический пример: SwapПередача массивов в функцииИтоги: указатели как аргументы функций8Структуры и указатели
Указатели на структурыОператор «стрелка» (->)Передача структур по значениюПередача указателей на структурыДинамическое выделение памяти для структурИтоги: Изменение структур через указатели11Итоговые задачи на повторение
Повторение: динамическая конкатенация строкПовторение: массив структурПовторение: счетчик частоты слов3Символьные массивы и строки
Строки как массивы charНуль-терминаторВвод строк с помощью scanfИспользование strlen()Использование strcpy()Использование strcat()Использование strcmp()Итоги: основные строковые функции6Управление памятью
Стек против кучиДинамическое выделение — malloc()Использование sizeof() для выделения памятиПроверка ошибок выделения памятиОсвобождение памяти с помощью free()Выделение памяти с помощью calloc()Итоги: Динамический массив