Verificare il fallimento dell'allocazione
Fa parte della sezione Logica e flusso del percorso C di Coddy. Lezione 34 di 63.
Sebbene malloc() sia uno strumento potente per l'allocazione dinamica della memoria, c'è una realtà fondamentale che devi comprendere: malloc() può fallire. Quando il sistema esaurisce la memoria disponibile, malloc() non può soddisfare la tua richiesta e restituisce NULL invece di un indirizzo di memoria valido.
Questo significa che ogni volta che usi malloc(), devi verificare che abbia avuto successo prima di provare a usare il puntatore restituito. L’uso di un puntatore NULL farà arrestare il programma con un errore di segmentazione.
int *ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed!\n");
return -1; // Esci dal programma o gestisci l'errore
}
// Qui si può usare ptr in sicurezza
*ptr = 42;Questo controllo di NULL non è facoltativo: è essenziale per scrivere programmi C robusti. Anche se gli errori di allocazione della memoria sono rari nei sistemi moderni, possono verificarsi, soprattutto in ambienti con risorse limitate o quando si richiedono grandi quantità di memoria. Il codice C professionale include sempre questi controlli per prevenire arresti anomali e gestire gli errori in modo appropriato.
Sfida
FacileScrivi un programma in C che dimostri la corretta gestione degli errori quando si usa malloc() per l’allocazione dinamica della memoria. Il programma deve:
- Leggere dall’utente un intero
nche rappresenta il numero di interi da memorizzare - Usare
malloc()consizeof()per allocare dinamicamente la memoria per un array dininteri - Verificare se l’allocazione della memoria è riuscita controllando se il puntatore restituito è
NULL - Se l’allocazione non riesce, stampare
Memory allocation failed!e terminare il programma - Se l’allocazione riesce, stampare
Memory allocation successful! - Leggere dall’utente
nvalori interi e memorizzarli nell’array allocato - Calcolare e stampare la somma di tutti i valori nel formato:
Sum: [value] - Stampare il totale dei byte allocati nel formato:
Bytes allocated: [value]
Ricorda di includere l’header <stdlib.h> per usare malloc(). Il programma deve dimostrare la pratica essenziale di verificare che l’allocazione sia riuscita prima di provare a usare la memoria allocata.
Per esempio, se l’input è:
4
10 20 30 40L’output dovrebbe essere:
Memory allocation successful!
Sum: 100
Bytes allocated: 16Questa sfida sottolinea l’importanza fondamentale della programmazione difensiva quando si lavora con l’allocazione dinamica della memoria, assicurandosi che i programmi gestiscano con eleganza i possibili errori di allocazione della memoria invece di bloccarsi inaspettatamente.
Provalo tu
#include <stdio.h>
#include <stdlib.h>
int main() {
// Leggi il numero di interi
int n;
scanf("%d", &n);
// TODO: Scrivi il tuo codice qui
// - Usa malloc() per allocare memoria per n interi
// - Controlla se l'allocazione è riuscita
// - Gestisci sia il caso di successo sia quello di errore
// - Leggi gli interi e memorizzali
// - Calcola la somma e il numero di byte allocati
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 funzioni3Array 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