Menu
Coddy logo textTech

Copie profonde

Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 15 sur 61.

Lorsque vous affectez une structure à une autre en C, vous obtenez une copie superficielle : tous les champs sont copiés octet par octet. Cela fonctionne parfaitement pour des valeurs simples comme les entiers, mais crée un problème avec les pointeurs : les deux structures finissent par pointer vers la même zone mémoire.

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

Person alice = {"Alice", 30};
Person copy = alice;  // Copie superficielle !
// alice.name et copy.name pointent tous les deux vers la MÊME chaîne

Si tu en libères un, l’autre devient invalide. Si tu modifies la chaîne par l’intermédiaire de l’un, les deux voient la modification. C’est rarement ce que tu souhaites.

Une copie profonde alloue une nouvelle zone mémoire pour les membres pointeurs et copie les données réelles :

Person *clone_person(const Person *original) {
    Person *copy = malloc(sizeof(Person));
    copy->name = malloc(strlen(original->name) + 1);
    strcpy(copy->name, original->name);
    copy->age = original->age;
    return copy;
}

Désormais, chaque objet possède sa propre chaîne. Vous pouvez en modifier ou en libérer une sans affecter l’autre. Le principe est simple : pour chaque membre pointeur, allouez une nouvelle zone mémoire et copiez le contenu, pas seulement l’adresse.

challenge icon

Défi

Facile

Construisons un module Student qui illustre le modèle de copie profonde. Vous allez créer une fonction de clonage qui produit une copie complètement indépendante d’un objet étudiant : modifier ou libérer l’original n’aura aucun effet sur le clone.

Vous allez créer trois fichiers :

  • student.h : déclarer une structure Student avec deux membres : char *name (une chaîne allouée dynamiquement) et int grade. Déclarer trois fonctions :
    • create_student : constructeur qui prend un nom et une note, et renvoie un pointeur vers un nouveau Student
    • clone_student : prend un const Student * et renvoie un pointeur vers une nouvelle copie indépendante
    • free_student : destructeur qui libère correctement toute la mémoire allouée
    Utiliser des gardes d’inclusion avec le symbole STUDENT_H.
  • student.c : implémenter les trois fonctions. Votre fonction clone_student est l’élément clé. Elle doit allouer une nouvelle zone mémoire pour la structure et pour la chaîne du nom, puis copier les données réelles de la chaîne (et pas seulement l’adresse du pointeur). Cela garantit que le clone possède sa propre mémoire, complètement séparée de celle de l’original.
  • main.c : créer un étudiant, le cloner, afficher les informations des deux étudiants, puis nettoyer correctement les deux objets.

Vous recevrez deux entrées : le nom de l’étudiant (une chaîne) et la note (un entier).

Dans votre fichier principal, créer un étudiant avec les valeurs fournies, puis créer un clone de cet étudiant. Afficher les informations de l’original et du clone pour vérifier qu’ils contiennent les mêmes données. Enfin, libérer les deux étudiants et afficher une confirmation.

Afficher la sortie dans ce format :

Original: {name}, Grade: {grade}
Clone: {name}, Grade: {grade}
Both freed

Par exemple, avec les entrées Alice et 95, la sortie serait :

Original: Alice, Grade: 95
Clone: Alice, Grade: 95
Both freed

Le modèle de copie profonde garantit que chaque objet est véritablement indépendant : le clone possède sa propre chaîne allouée, et non un pointeur partagé vers la mémoire de l’original.

Essayez vous-même

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

int main() {
    char name[100];
    int grade;
    
    // Lire l'entrée
    scanf("%s", name);
    scanf("%d", &grade);
    
    // TODO: Créer un étudiant avec le nom et la note fournis
    
    // TODO: Créer un clone de l'étudiant
    
    // TODO: Print the original student's information
    // Format : "Original: {name}, Grade: {grade}"
    
    // TODO: Afficher les informations du clone
    // Format : "Clone: {name}, Grade: {grade}"
    
    // TODO: Libérer les deux étudiants
    
    // Afficher la confirmation
    printf("Both freed\n");
    
    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 Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C en ligne