Menu
Coddy logo textTech

Copia profunda

Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 15 de 61.

Cuando asignas una estructura a otra en C, obtienes una copia superficial: todos los campos se copian byte a byte. Esto funciona bien para valores simples como los enteros, pero crea un problema con los punteros: ambas estructuras terminan apuntando a la misma memoria.

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

Person alice = {"Alice", 30};
Person copy = alice;  // ¡Copia superficial!
// Tanto alice.name como copy.name apuntan a la MISMA cadena

Si liberas uno, el otro deja de ser válido. Si modificas la cadena a través de uno, ambos ven el cambio. Esto rara vez es lo que quieres.

Una copia profunda asigna nueva memoria para los miembros puntero y copia los datos reales:

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;
}

Ahora cada objeto es propietario de su propia cadena. Puedes modificar o liberar una sin afectar a la otra. El patrón es sencillo: para cada miembro puntero, asigna memoria nueva y copia el contenido, no solo la dirección.

challenge icon

Desafío

Fácil

Vamos a crear un módulo Student que demuestre el patrón de copia profunda. Crearás una función de clonación que produzca una copia completamente independiente de un objeto estudiante: una en la que modificar o liberar el original no tenga ningún efecto sobre el clon.

Crearás tres archivos:

  • student.h: Declara una estructura Student con dos miembros: char *name (una cadena asignada dinámicamente) y int grade. Declara tres funciones:
    • create_student: constructor que recibe un nombre y una calificación, y devuelve un puntero a un nuevo Student
    • clone_student: recibe un const Student * y devuelve un puntero a una copia nueva e independiente
    • free_student: destructor que libera correctamente toda la memoria asignada
    Usa protecciones de inclusión con el símbolo STUDENT_H.
  • student.c: Implementa las tres funciones. Tu función clone_student es la clave. Debe asignar memoria nueva tanto para la estructura como para la cadena de nombre y, después, copiar los datos reales de la cadena (no solo la dirección del puntero). Esto garantiza que el clon sea completamente propietario de su propia memoria, separada de la del original.
  • main.c: Crea un estudiante, clónalo, muestra la información de ambos estudiantes y, después, limpia correctamente ambos objetos.

Recibirás dos entradas: el nombre del estudiante (una cadena) y la calificación (un entero).

En tu archivo principal, crea un estudiante con los valores proporcionados y, después, crea un clon de ese estudiante. Imprime la información tanto del original como del clon para verificar que contienen los mismos datos. Finalmente, libera ambos estudiantes e imprime una confirmación.

Imprime la salida con este formato:

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

Por ejemplo, con las entradas Alice y 95, la salida sería:

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

El patrón de copia profunda garantiza que cada objeto sea verdaderamente independiente: el clon tiene su propia cadena asignada, no un puntero compartido a la memoria del original.

Pruébalo tú mismo

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

int main() {
    char name[100];
    int grade;
    
    // Leer la entrada
    scanf("%s", name);
    scanf("%d", &grade);
    
    // TODO: Crea un estudiante con el nombre y la calificación proporcionados
    
    // TODO: Crea un clon del estudiante
    
    // TODO: Print the original student's information
    // Formato: "Original: {name}, Grade: {grade}"
    
    // TODO: Imprime la información del clon
    // Formato: "Clone: {name}, Grade: {grade}"
    
    // TODO: Libera ambos estudiantes
    
    // Imprimir confirmación
    printf("Both freed\n");
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C online