Allocazione dinamica delle struct
Fa parte della sezione Logica e flusso del percorso C di Coddy. Lezione 48 di 63.
Finora hai imparato a creare struct nello stack: esistono all'interno dell'ambito in cui vengono dichiarate e vengono eliminate automaticamente quando tale ambito termina. Ma cosa succede se hai bisogno che una struct persista oltre il suo ambito originale, o se non sai in fase di compilazione di quante struct avrai bisogno?
È qui che entra in gioco l’allocazione dinamica. Puoi usare malloc() per creare strutture nell’heap, proprio come faresti per qualsiasi altro tipo di dato. La differenza fondamentale è che le strutture allocate dinamicamente rimangono in memoria finché non le liberi esplicitamente con free().
Ecco la sintassi per allocare dinamicamente una struct:
struct Point *ptr = malloc(sizeof(struct Point));Questo alloca memoria sufficiente nell'heap per contenere una struct Point e restituisce un puntatore a quella memoria. Puoi quindi usare l'operatore freccia per accedere ai membri della struct e modificarli:
ptr->x = 10;
ptr->y = 20;Ricorda di controllare sempre se malloc() ha avuto successo (ha restituito un valore diverso da NULL) e di chiamare free(ptr) quando hai finito con la struct, per evitare perdite di memoria. Questa tecnica è essenziale per creare programmi flessibili in grado di creare e gestire strutture dati in fase di esecuzione.
Sfida
FacileCrea un programma C che dimostri l’allocazione dinamica di struct usando malloc(). Il tuo programma deve:
- Definire una
structdenominataCarcon i seguenti membri:- Un intero
yearper memorizzare l’anno di produzione - Un array di caratteri
branddi dimensione 20 per memorizzare la marca dell’auto - Un array di caratteri
modeldi dimensione 25 per memorizzare il modello dell’auto - Un float
priceper memorizzare il prezzo dell’auto - Un intero
mileageper memorizzare il chilometraggio dell’auto
- Un intero
- Nella funzione main, dichiarare un puntatore a una struct
CardenominatocarPtr - Usare
malloc()per allocare dinamicamente memoria per una structCare assegnare l’indirizzo restituito acarPtr - Verificare che l’allocazione della memoria sia riuscita:
- Se
carPtrèNULL, stampareMemory allocation failede uscire dal programma - Se l’allocazione è riuscita, stampare
Memory allocation successful
- Se
- Leggere i seguenti valori di input e assegnarli ai membri della struct usando l’operatore freccia:
- Leggere un intero per l’anno e assegnarlo usando
carPtr->year - Leggere una stringa per la marca e assegnarla usando
carPtr->brand - Leggere una stringa per il modello e assegnarla usando
carPtr->model - Leggere un float per il prezzo e assegnarlo usando
carPtr->price - Leggere un intero per il chilometraggio e assegnarlo usando
carPtr->mileage
- Leggere un intero per l’anno e assegnarlo usando
- Dopo aver letto tutti i valori, eseguire i seguenti calcoli usando l’operatore freccia:
- Calcolare l’età dell’auto sottraendo l’anno da 2024:
int age = 2024 - carPtr->year; - Calcolare il tasso di svalutazione in base all’età: se l’età è maggiore di 10, impostare depreciation su 0.6, altrimenti impostarla su 0.8
- Calcolare il valore attuale:
carPtr->price * depreciation
- Calcolare l’età dell’auto sottraendo l’anno da 2024:
- Stampare le informazioni sull’auto usando l’operatore freccia in questo formato esatto:
Car Information:Year: [year]Brand: [brand]Model: [model]Original Price: [price]Mileage: [mileage]Age: [age] yearsCurrent Value: [current_value]
- Liberare la memoria allocata dinamicamente usando
free(carPtr) - Stampare
Memory freed successfully
Questa sfida verifica la tua comprensione dell’allocazione dinamica delle struct usando malloc(), del controllo degli errori di allocazione, dell’accesso ai membri delle struct tramite puntatori usando l’operatore freccia e della corretta liberazione della memoria allocata con free(). Ti eserciterai nell’intero ciclo di gestione della memoria dinamica con le struct.
Provalo tu
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO: Define aquí la estructura Car
int main() {
// TODO: Declara un puntero a la estructura Car llamado carPtr
// TODO: Usa malloc() para reservar memoria para una estructura Car
// TODO: Comprueba si la reserva de memoria se realizó correctamente
// Lee los valores de entrada
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: Asigna los valores de entrada a los miembros de la estructura usando el operador flecha
// TODO: Calcula la antigüedad, la depreciación y el valor actual
// TODO: Imprime la información del automóvil en el formato requerido
// TODO: Libera la memoria reservada e imprime un mensaje de éxito
return 0;
}Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Fondamenti dei puntatori
Che cos’è un puntatore?Dichiarare i puntatoriL’operatore di indirizzo (&)L’operatore di dereferenziazione (*)Puntatori NULLRiepilogo: nozioni di base sui puntatori4Progetto: Utility di testo semplice
Panoramica del progettoConteggio dei caratteri2Puntatori e array
I nomi degli array come puntatoriElementi degli array e puntatoriAritmetica dei puntatoriConfrontare i puntatoriRiepilogo: attraversamento di un array con i puntatori5Puntatori e funzioni
Passaggio per valorePassare puntatori alle funzioniModificare le variabili tramite puntatoriUn esempio classico: scambiare valoriPassare array alle funzioniRiepilogo: argomenti puntatore nelle funzioni8Struct e puntatori
Puntatori a structL’operatore freccia (->)Passare le struct per valorePassare puntatori a structAllocazione dinamica delle structRiepilogo: modifica di una struct - puntatore3Array di caratteri e stringhe
Stringhe come array di charIl terminatore nullInput di stringhe con scanfUso di strlen()Uso di strcpy()Uso di strcat()Uso di strcmp()Riepilogo: funzioni di base per le stringhe6Gestione della memoria
Memoria Stack vs. HeapAllocazione dinamica - malloc()Usare sizeof() per l'allocazioneVerificare il fallimento dell'allocazioneLiberare la memoria con free()Allocare con calloc()Riepilogo: array dinamico9Progetto: Inserimento semplice di un contatto
Progetto: Definire una struct ContattoFunzione per creare un contattoEsercitati da solo: Compilatore C online