// Un struct que es owner de un bloque: reservar dos veces y liberar dos veces.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student {
    int code;
    char *name;
};

// Devuelve un estudiante nuevo, con su propia copia de name, o NULL si no hay memoria.
// Quien llama es owner del resultado, y lo libera con student_free.
struct student *student_new(int code, const char *name) {
    struct student *s = malloc(sizeof *s);
    if (s == NULL) {
        return NULL;
    }

    s->name = malloc(strlen(name) + 1);
    if (s->name == NULL) {
        free(s);
        return NULL;
    }

    strcpy(s->name, name);
    s->code = code;
    return s;
}

// Libera el estudiante y su nombre. Con NULL no hace nada.
void student_free(struct student *s) {
    if (s == NULL) {
        return;
    }
    free(s->name);
    free(s);
}

int main(void) {
    struct student *ana = student_new(101, "Ana");
    if (ana == NULL) {
        return 1;
    }

    // Copiar el struct copia el puntero, no el nombre: ahora los dos comparten un bloque.
    struct student shallow = *ana;
    shallow.name[0] = 'E';
    printf("%s %s\n", ana->name, shallow.name);
    printf("mismo bloque: %d\n", ana->name == shallow.name);

    student_free(ana);
    return 0;
}
