Проверка ошибок выделения памяти
Часть раздела Logic & Flow путешествия по C на Coddy — урок 34 из 63.
Хотя malloc() является мощным инструментом для динамического выделения памяти, существует важный нюанс, который необходимо понимать: malloc() может завершиться ошибкой. Когда в системе заканчивается доступная память, malloc() не может выполнить ваш запрос и возвращает NULL вместо корректного адреса памяти.
Это означает, что каждый раз, когда вы используете malloc(), вы должны проверять, успешно ли выполнилась операция, прежде чем пытаться использовать возвращенный указатель. Использование указателя NULL приведет к аварийному завершению программы с ошибкой сегментации (segmentation fault).
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // Завершить программу или обработать ошибку
}
// Здесь ptr можно безопасно использовать
*ptr = 42;Эта проверка на NULL не является необязательной — она необходима для написания надежных программ на C. Даже если ошибки выделения памяти редко встречаются в современных системах, они могут случаться, особенно в средах с ограниченными ресурсами или при запросе больших объемов памяти. Профессиональный код на C всегда включает такие проверки, чтобы предотвратить сбои и обеспечить корректную обработку ошибок.
Задание
ЛегкоНапишите программу на языке C, которая демонстрирует правильную обработку ошибок при использовании malloc() для динамического выделения памяти. Ваша программа должна:
- Считать целое число
nот пользователя, представляющее количество целых чисел для хранения - Использовать
malloc()вместе сsizeof()для динамического выделения памяти под массив изnцелых чисел - Проверить, было ли выделение памяти успешным, протестировав, не является ли возвращенный указатель
NULL - Если выделение памяти не удалось, вывести
Memory allocation failed!и завершить выполнение программы - Если выделение памяти прошло успешно, вывести
Memory allocation successful! - Считать
nцелых чисел от пользователя и сохранить их в выделенном массиве - Вычислить и вывести сумму всех значений в формате:
Sum: [value] - Вывести общее количество выделенных байт в формате:
Bytes allocated: [value]
Не забудьте включить заголовочный файл <stdlib.h> для использования malloc(). Ваша программа должна демонстрировать важную практику проверки на ошибку выделения памяти перед попыткой использования этой памяти.
Например, если входные данные:
4
10 20 30 40Ваш вывод должен быть следующим:
Memory allocation successful!
Sum: 100
Bytes allocated: 16Эта задача подчеркивает критическую важность защитного программирования при работе с динамическим выделением памяти, гарантируя, что ваши программы корректно обрабатывают возможные сбои выделения памяти, а не завершаются аварийно.
Шпаргалка
Всегда проверяйте, возвращает ли malloc() значение NULL перед использованием выделенной памяти:
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // Выход из программы или обработка ошибки
}
// Здесь можно безопасно использовать ptr
*ptr = 42;malloc() может завершиться ошибкой, когда в системе заканчивается доступная память. Использование указателя NULL приведет к ошибке сегментации (segmentation fault). Эта проверка на NULL необходима для написания надежных программ на C и предотвращения сбоев.
Попробуйте сами
#include <stdio.h>
#include <stdlib.h>
int main() {
// Считать количество целых чисел
int n;
scanf("%d", &n);
// TODO: Напишите свой код здесь
// - Используйте malloc() для выделения памяти для n целых чисел
// - Проверьте, было ли выделение памяти успешным
// - Обработайте случаи успеха и неудачи
// - Считайте целые числа и сохраните их
// - Вычислите сумму и количество выделенных байт
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Основы указателей
Что такое указатель?Объявление указателейОператор взятия адреса (&)Оператор разыменования (*)Указатели NULLИтоги: Основы указателей4Проект: Простая текстовая утилита
Обзор проектаПодсчет символов2Указатели и массивы
Имена массивов как указателиЭлементы массива — указателиАрифметика указателейСравнение указателейИтоги: Обход массива через указатели5Указатели и функции
Передача по значениюПередача указателей в функцииИзменение переменных через указателиКлассический пример: SwapПередача массивов в функцииИтоги: указатели как аргументы функций8Структуры и указатели
Указатели на структурыОператор «стрелка» (->)Передача структур по значениюПередача указателей на структурыДинамическое выделение памяти для структурИтоги: Изменение структур через указатели11Итоговые задачи на повторение
Повторение: динамическая конкатенация строкПовторение: массив структурПовторение: счетчик частоты слов3Символьные массивы и строки
Строки как массивы charНуль-терминаторВвод строк с помощью scanfИспользование strlen()Использование strcpy()Использование strcat()Использование strcmp()Итоги: основные строковые функции6Управление памятью
Стек против кучиДинамическое выделение — malloc()Использование sizeof() для выделения памятиПроверка ошибок выделения памятиОсвобождение памяти с помощью free()Выделение памяти с помощью calloc()Итоги: Динамический массив