Использование sizeof() для выделения памяти
Часть раздела Logic & Flow путешествия по C на Coddy — урок 33 из 63.
Хотя malloc() позволяет динамически выделять память, существует важная передовая практика, которая делает ваш код более переносимым и поддерживаемым: использование оператора sizeof() для определения количества байтов, которые необходимо выделить.
Оператор sizeof() возвращает количество байтов, необходимых для хранения определенного типа данных в вашей системе. Вместо того чтобы жестко задавать размеры в байтах, вы можете позволить sizeof() автоматически вычислить правильное значение:
// Вместо того чтобы угадывать размеры в байтах:
int *ptr = (int*)malloc(4); // Предполагается, что int занимает 4 байта
// Используйте sizeof() для переносимости:
int *ptr = (int*)malloc(sizeof(int)); // Всегда правильноЭтот подход становится особенно ценным при выделении памяти под массивы. Чтобы выделить место для нескольких элементов, умножьте количество элементов на размер каждого элемента:
// Выделение памяти для 10 целых чисел
int *arr = (int*)malloc(10 * sizeof(int));
// Выделение памяти для 5 чисел типа double
double *values = (double*)malloc(5 * sizeof(double));Использование sizeof() позволяет вашему коду корректно работать на различных системах, где типы данных могут иметь разные размеры, и это четко передает ваше намерение выделить место для определенного количества элементов конкретного типа.
Задание
ЛегкоНапишите программу на языке C, которая демонстрирует правильное использование sizeof() вместе с malloc() для динамического выделения памяти. Ваша программа должна:
- Считать целое число
nот пользователя, представляющее количество элементов для выделения памяти - Использовать
malloc()сsizeof()для динамического выделения памяти под массив изnзначений типа double - Привести возвращаемый указатель типа void к указателю на double
- Считать
nзначений типа double от пользователя и сохранить их в выделенном массиве - Вычислить общий объем выделенной памяти в байтах и вывести его в формате:
Memory allocated: [bytes] bytes - Вычислить и вывести среднее арифметическое всех значений ровно с 2 знаками после запятой в формате:
Average: [value] - Найти и вывести наибольшее значение ровно с 2 знаками после запятой в формате:
Largest: [value]
Не забудьте включить заголовочный файл <stdlib.h> для использования malloc(). Ваша программа должна демонстрировать, как sizeof() обеспечивает корректное выделение памяти независимо от размеров типов данных в системе.
Например, если входные данные:
3
2.5 7.8 4.1Ваш вывод должен быть:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80Эта задача подчеркивает важность использования sizeof() для того, чтобы сделать динамическое выделение памяти переносимым и удобным в сопровождении, автоматически вычисляя правильное количество байтов, необходимых для любого типа данных в любой системе.
Шпаргалка
Используйте оператор sizeof() вместе с malloc(), чтобы определить правильное количество байтов для выделения под любой тип данных:
// Переносимое выделение памяти
int *ptr = (int*)malloc(sizeof(int));
// Выделение памяти под массивы
int *arr = (int*)malloc(10 * sizeof(int));
double *values = (double*)malloc(5 * sizeof(double));Оператор sizeof() возвращает количество байтов, необходимых для хранения типа данных в вашей системе, что делает ваш код переносимым между различными платформами, где типы данных могут иметь разные размеры.
Попробуйте сами
#include <stdio.h>
#include <stdlib.h>
int main() {
// Считать количество элементов
int n;
scanf("%d", &n);
// TODO: Напишите свой код ниже
// 1. Выделить память для n значений типа double, используя malloc() и sizeof()
// 2. Привести возвращаемый указатель к типу double*
// 3. Считать n значений типа double и сохранить их в выделенном массиве
// 4. Вычислить и вывести объем выделенной памяти в байтах
// 5. Вычислить и вывести среднее значение с 2 знаками после запятой
// 6. Найти и вывести наибольшее значение с 2 знаками после запятой
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Основы указателей
Что такое указатель?Объявление указателейОператор взятия адреса (&)Оператор разыменования (*)Указатели NULLИтоги: Основы указателей4Проект: Простая текстовая утилита
Обзор проектаПодсчет символов2Указатели и массивы
Имена массивов как указателиЭлементы массива — указателиАрифметика указателейСравнение указателейИтоги: Обход массива через указатели5Указатели и функции
Передача по значениюПередача указателей в функцииИзменение переменных через указателиКлассический пример: SwapПередача массивов в функцииИтоги: указатели как аргументы функций8Структуры и указатели
Указатели на структурыОператор «стрелка» (->)Передача структур по значениюПередача указателей на структурыДинамическое выделение памяти для структурИтоги: Изменение структур через указатели11Итоговые задачи на повторение
Повторение: динамическая конкатенация строкПовторение: массив структурПовторение: счетчик частоты слов3Символьные массивы и строки
Строки как массивы charНуль-терминаторВвод строк с помощью scanfИспользование strlen()Использование strcpy()Использование strcat()Использование strcmp()Итоги: основные строковые функции6Управление памятью
Стек против кучиДинамическое выделение — malloc()Использование sizeof() для выделения памятиПроверка ошибок выделения памятиОсвобождение памяти с помощью free()Выделение памяти с помощью calloc()Итоги: Динамический массив