cours La mémoire : qui possède quoi 4/5

Libéré deux fois

Un clone partage ses chaînes avec l'original. Les deux les libèrent. Décidez qui possède quoi.

Leçon

L'idée : copier une struct copie les pointeurs, pas ce qu'ils désignent

*c = *d est une copie superficielle : les deux champs char * sont copiés, donc le clone et l'original pointent vers les mêmes chaînes. Chacun croit les posséder. Chacun les libère. Le second free est un double free.

La règle qui l'évite : un pointeur libéré doit avoir un seul propriétaire.

La situation

doc_clone doit renvoyer un document totalement indépendant : modifier ou libérer l'un ne doit jamais affecter l'autre.

Votre mission

Lancez le sanitizer. Selon la ligne exécutée en premier, il signale un double free ou un use-after-free, et dans les deux cas il nomme l'endroit où le bloc a été alloué et celui où il a été libéré une première fois. Servez-vous-en pour dire au junior ce que doc_clone doit faire pour que chaque Doc possède des chaînes privées.

À surveiller

  • « Ne libère pas deux fois » n'est pas une conception. Libérer moins fait fuir, et le partage reste là.
  • Regardez comment doc_new crée ses chaînes. Le clone doit faire pareil.

Essayez cet exercice

Créez un compte gratuit pour dire au junior IA quoi changer, lancer les tests et le vérificateur mémoire, et obtenir un code de complétion vérifiable.

Code de départ
doc.c
#include "doc.h"#include <stdlib.h>#include <string.h> Doc *doc_new(const char *title, const char *body) {    Doc *d = malloc(sizeof *d);    if (!d) return NULL;    d->title = strdup(title);    d->body = strdup(body);    return d;} Doc *doc_clone(const Doc *d) {    Doc *c = malloc(sizeof *c);    if (!c) return NULL;    *c = *d;    return c;} void doc_set_body(Doc *d, const char *body) {    free(d->body);    d->body = strdup(body);} void doc_free(Doc *d) {    if (!d) return;    free(d->title);    free(d->body);    free(d);}
doc.h
#ifndef DOC_H#define DOC_H typedef struct {    char *title;    char *body;} Doc; /* Creates a document that owns private copies of title and body. */Doc *doc_new(const char *title, const char *body); /* Creates an independent duplicate: changing or freeing one must never affect the other. */Doc *doc_clone(const Doc *d); /* Replaces the body with a private copy of `body`. */void doc_set_body(Doc *d, const char *body); /* Frees the document and everything it owns. */void doc_free(Doc *d);#endif