Menu
Coddy logo textTech

Pattern de destructeur

Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 13 sur 61.

Chaque objet créé avec malloc doit finir par être libéré. Tout comme nous avons écrit une fonction create_ pour gérer l'allocation, nous écrivons une fonction free_ pour gérer le nettoyage. C'est le patron de conception destructeur (destructor pattern).

L'idée clé est que la libération doit se faire dans l'ordre inverse de l'allocation. Si votre constructeur a alloué les membres internes en premier, puis la structure elle-même, votre destructeur doit libérer les membres de la structure en premier, puis la structure elle-même :

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

void free_person(Person *p) {
    if (p == NULL) return;  // Vérification de sécurité
    free(p->name);          // Libérer d'abord le membre interne
    free(p);                // Puis libérer la structure elle-même
}

La vérification NULL au début empêche les plantages si quelqu'un passe accidentellement un pointeur invalide. Après avoir libéré la chaîne interne name, nous libérons la structure elle-même. Si nous libérions p en premier, nous perdrions l'accès à p->name et provoquerions une fuite de mémoire.

L'utilisation du destructeur est simple :

Person *alice = create_person("Alice", 30);
// ... utiliser alice ...
free_person(alice);  // Nettoyer une fois terminé

Ce modèle garantit que toute la mémoire est correctement libérée. Sans cela, chaque objet que vous créez entraînerait une fuite de mémoire jusqu'à ce que votre programme s'épuise.

challenge icon

Défi

Facile

Construisons un module Movie qui illustre le cycle de vie complet d'un objet — à la fois sa création et sa destruction. Vous allez vous entraîner à écrire une fonction destructeur qui nettoie correctement toute la mémoire allouée dans le bon ordre.

Vous allez créer trois fichiers :

  • movie.h : Déclarez une structure Movie avec deux membres : char *title (une chaîne de caractères allouée dynamiquement) et int year. Déclarez à la fois un constructeur create_movie qui prend un titre et une année, et un destructeur free_movie qui prend un pointeur Movie. Utilisez des gardes d'inclusion avec le symbole MOVIE_H.
  • movie.c : Implémentez les deux fonctions. Votre constructeur doit allouer de la mémoire pour la structure et sa chaîne de titre (n'oubliez pas le terminateur nul). Votre destructeur doit libérer la mémoire dans l'ordre inverse de l'allocation — d'abord la chaîne interne title, puis la structure elle-même. Incluez une vérification NULL au début de votre destructeur par sécurité.
  • main.c : Créez un film, affichez ses informations, puis nettoyez correctement la mémoire.

Vous recevrez deux entrées : le titre du film (une chaîne de caractères) et l'année de sortie (un entier).

Dans votre fichier principal, utilisez create_movie pour créer un nouveau film, affichez ses informations, puis appelez free_movie pour libérer toute la mémoire. Après la libération, affichez un message de confirmation.

Affichez la sortie dans ce format :

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

Par exemple, avec les entrées Inception et 2010, la sortie serait :

Movie: Inception (2010)
Memory freed

Rappel : la clé d'un destructeur correct est de libérer dans l'ordre inverse. Ce que votre constructeur alloue en premier est libéré en dernier, et ce qu'il alloue en dernier est libéré en premier.

Aide-mémoire

Chaque objet créé avec malloc doit être libéré à l'aide d'une fonction destructeur. Les destructeurs suivent le principe de libération de la mémoire dans l'ordre inverse de l'allocation.

Structure de base d'un destructeur :

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

void free_person(Person *p) {
    if (p == NULL) return;  // Safety check
    free(p->name);          // Free internal members first
    free(p);                // Then free the struct itself
}

Principes clés :

  • Incluez toujours une vérification NULL au début pour éviter les plantages
  • Libérez les membres internes avant de libérer la structure elle-même
  • Si vous libérez la structure en premier, vous perdez l'accès à ses membres et provoquez des fuites de mémoire

Exemple d'utilisation :

Person *alice = create_person("Alice", 30);
// ... use alice ...
free_person(alice);  // Clean up when done

Essayez vous-même

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

int main() {
    char title[100];
    int year;
    
    // Lire l'entrée
    scanf("%[^\n]", title);
    scanf("%d", &year);
    
    // TODO: Créer un film en utilisant create_movie
    
    // TODO: Afficher les informations du film au format :
    // Movie: {title} ({year})
    
    // TODO: Libérer le film en utilisant free_movie
    
    // TODO: Afficher "Memory freed"
    
    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming