courses Memory: who owns what 4/5

Freed Twice

A clone shares its strings with the original. Both owners free them. Decide who owns what.

Lesson

The idea: copying a struct copies pointers, not what they point to

*c = *d is a shallow copy: the two char * fields are copied, so the clone and the original now point to the same strings. Each of them thinks it owns those strings. Each frees them. The second free is a double free.

The rule that prevents it: a pointer that gets freed must have exactly one owner.

The situation

doc_clone must return a fully independent document: changing or freeing one must never affect the other.

Your mission

Run the sanitizer. Depending on which line runs first it reports a double free or a use-after-free, and either way it names where the block was allocated and where it was first freed. Use that to tell the junior what doc_clone must do so that each Doc owns private strings.

What to watch for

  • "Just don't free it twice" is not a design. Freeing less leaks, and the sharing is still there.
  • Look at how doc_new creates its strings. The clone must do the same.

Try this exercise

Create a free account to tell the AI junior what to change, run the tests and the memory checker, and earn a completion code you can verify.

Starting code
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