Menu
Coddy logo textTech

Динамическое выделение памяти для структур

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

До сих пор вы узнали, как создавать структуры в стеке — они существуют в той области видимости, где они объявлены, и автоматически удаляются по её завершении. Но что, если вам нужно, чтобы структура сохранялась за пределами своей исходной области видимости, или если вы не знаете во время компиляции, сколько структур вам потребуется?

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

Вот синтаксис для динамического выделения памяти для структуры:

struct Point *ptr = malloc(sizeof(struct Point));

Это выделяет в куче достаточно памяти для хранения одной структуры Point и возвращает указатель на эту память. Затем вы можете использовать оператор «стрелка» для доступа к членам структуры и их изменения:

ptr->x = 10;
ptr->y = 20;

Не забывайте всегда проверять, успешно ли выполнилась функция malloc() (вернула значение, отличное от NULL), и вызывать free(ptr), когда вы закончите работу со структурой, чтобы предотвратить утечки памяти. Этот метод необходим для создания гибких программ, которые могут создавать структуры данных и управлять ими во время выполнения.

challenge icon

Задание

Легко

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

  1. Определить struct с именем Car со следующими полями:
    • Целое число year для хранения года выпуска
    • Символьный массив brand размером 20 для хранения марки автомобиля
    • Символьный массив model размером 25 для хранения модели автомобиля
    • Число с плавающей точкой price для хранения цены автомобиля
    • Целое число mileage для хранения пробега автомобиля
  2. В функции main объявите указатель на структуру Car с именем carPtr
  3. Используйте malloc() для динамического выделения памяти для одной структуры Car и присвойте возвращенный адрес указателю carPtr
  4. Проверьте, было ли выделение памяти успешным:
    • Если carPtr равен NULL, выведите Memory allocation failed и завершите программу
    • Если выделение памяти прошло успешно, выведите Memory allocation successful
  5. Считайте следующие входные значения и присвойте их полям структуры, используя оператор стрелка:
    • Считайте целое число для года и присвойте его с помощью carPtr->year
    • Считайте строку для марки и присвойте ее с помощью carPtr->brand
    • Считайте строку для модели и присвойте ее с помощью carPtr->model
    • Считайте число с плавающей точкой для цены и присвойте его с помощью carPtr->price
    • Считайте целое число для пробега и присвойте его с помощью carPtr->mileage
  6. После считывания всех значений выполните следующие вычисления, используя оператор стрелка:
    • Вычислите возраст автомобиля, вычтя год выпуска из 2024: int age = 2024 - carPtr->year;
    • Рассчитайте коэффициент амортизации в зависимости от возраста: если возраст больше 10 лет, установите амортизацию равной 0.6, в противном случае — 0.8
    • Вычислите текущую стоимость: carPtr->price * depreciation
  7. Выведите информацию об автомобиле, используя оператор стрелка, в следующем формате:
    • Car Information:
    • Year: [year]
    • Brand: [brand]
    • Model: [model]
    • Original Price: [price]
    • Mileage: [mileage]
    • Age: [age] years
    • Current Value: [current_value]
  8. Освободите динамически выделенную память с помощью free(carPtr)
  9. Выведите Memory freed successfully

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

Шпаргалка

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

struct Point *ptr = malloc(sizeof(struct Point));

Обращайтесь к членам структуры через указатели, используя оператор «стрелка»:

ptr->x = 10;
ptr->y = 20;

Всегда проверяйте, успешно ли выполнилась malloc(), и освобождайте память по завершении работы:

if (ptr == NULL) {
    // Обработка ошибки выделения памяти
}
// Использование структуры...
free(ptr);

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

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

// TODO: Определите структуру Car здесь

int main() {
    // TODO: Объявите указатель на структуру Car с именем carPtr
    
    // TODO: Используйте malloc() для выделения памяти для одной структуры Car
    
    // TODO: Проверьте, было ли выделение памяти успешным
    
    // Считайте входные значения
    int year, mileage;
    char brand[20], model[25];
    float price;
    
    scanf("%d", &year);
    scanf("%s", brand);
    scanf("%s", model);
    scanf("%f", &price);
    scanf("%d", &mileage);
    
    // TODO: Присвойте входные значения членам структуры, используя оператор стрелка
    
    // TODO: Рассчитайте возраст, амортизацию и текущую стоимость
    
    // TODO: Выведите информацию об автомобиле в требуемом формате
    
    // TODO: Освободите выделенную память и выведите сообщение об успехе
    
    return 0;
}
quiz iconПроверьте себя

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

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