Menu
Coddy logo textTech

Pattern del distruttore

Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 13 di 61.

Ogni oggetto creato con malloc deve essere infine liberato. Proprio come abbiamo scritto una funzione create_ per gestire l'allocazione, scriviamo una funzione free_ per gestire la pulizia. Questo è il modello del distruttore.

L’intuizione chiave è che la liberazione deve avvenire in ordine inverso rispetto all’allocazione. Se il tuo costruttore ha allocato prima i membri interni e poi la struct stessa, il tuo distruttore deve liberare prima i membri della struct e poi la struct:

typedef struct {
    char *name;
    int age;
} Person;

void free_person(Person *p) {
    if (p == NULL) return;  // Controllo di sicurezza
    free(p->name);          // Libera prima il membro interno
    free(p);                // Poi libera la struct stessa
}

Il controllo NULL all'inizio previene gli arresti anomali se qualcuno passa accidentalmente un puntatore non valido. Dopo aver liberato la stringa interna name, liberiamo la struct stessa. Se liberassimo prima p, perderemmo l'accesso a p->name e causeremmo una perdita di memoria.

Usare il distruttore è semplice:

Person *alice = create_person("Alice", 30);
// ... usa alice ...
free_person(alice);  // Libera le risorse quando hai finito

Questo schema assicura che tutta la memoria venga rilasciata correttamente. Senza di esso, ogni oggetto che crei causerebbe una perdita di memoria fino a esaurire la memoria disponibile per il programma.

challenge icon

Sfida

Facile

Costruiamo un modulo Movie che dimostra l'intero ciclo di vita di un oggetto: sia la creazione sia la distruzione. Ti eserciterai a scrivere una funzione distruttrice che libera correttamente tutta la memoria allocata nell'ordine giusto.

Creerai tre file:

  • movie.h: dichiara una struct Movie con due membri: char *title (una stringa allocata dinamicamente) e int year. Dichiara sia un costruttore create_movie che accetta un titolo e un anno, sia un distruttore free_movie che accetta un puntatore a Movie. Usa le protezioni dalle inclusioni multiple con il simbolo MOVIE_H.
  • movie.c: implementa entrambe le funzioni. Il costruttore deve allocare memoria per la struct e per la sua stringa del titolo (non dimenticare il terminatore nullo). Il distruttore deve liberare la memoria nell'ordine inverso rispetto all'allocazione: prima la stringa interna title, poi la struct stessa. Per sicurezza, inserisci un controllo NULL all'inizio del distruttore.
  • main.c: crea un film, visualizza le sue informazioni, quindi libera correttamente la memoria.

Riceverai due input: il titolo del film (una stringa) e l'anno di uscita (un intero).

Nel file principale, usa create_movie per creare un nuovo film, stampane le informazioni, quindi chiama free_movie per liberare tutta la memoria. Dopo averla liberata, stampa un messaggio di conferma.

Stampa l'output in questo formato:

Movie: {title} ({year})
Memory freed

Per esempio, con gli input Inception e 2010, l'output sarebbe:

Movie: Inception (2010)
Memory freed

Ricorda: la chiave per un distruttore corretto è liberare la memoria nell'ordine inverso. Ciò che il costruttore alloca per primo viene liberato per ultimo, mentre ciò che alloca per ultimo viene liberato per primo.

Provalo tu

#include <stdio.h>
#include <stdlib.h>
#include "movie.h"

int main() {
    char title[100];
    int year;
    
    // Leggi l'input
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: Crea un film usando create_movie
    
    // TODO: Stampa le informazioni del film nel formato:
    // Movie: {title} ({year})
    
    // TODO: Libera la memoria del film usando free_movie
    
    // TODO: Stampa "Memory freed"
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C online