Menu
Coddy logo textTech

Copia profonda

Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 15 di 61.

Quando assegni una struct a un'altra in C, ottieni una copia superficiale: tutti i campi vengono copiati byte per byte. Funziona bene per valori semplici come gli interi, ma crea un problema con i puntatori: entrambe le struct finiscono per puntare alla stessa memoria.

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

Person alice = {"Alice", 30};
Person copy = alice;  // Copia superficiale!
// Sia alice.name sia copy.name puntano alla STESSA stringa

Se ne liberi uno, l'altro diventa non valido. Se modifichi la stringa tramite uno dei due, entrambi vedono la modifica. Raramente è ciò che vuoi.

Una copia profonda alloca nuova memoria per i membri puntatore e copia i dati effettivi:

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

Ora ogni oggetto possiede la propria stringa. Puoi modificarne o liberarne una senza influire sull’altra. Il modello è semplice: per ogni membro puntatore, alloca nuova memoria e copia i contenuti, non solo l’indirizzo.

challenge icon

Sfida

Facile

Costruiamo un modulo Student che illustra il modello della copia profonda. Creerai una funzione di clonazione che produce una copia completamente indipendente di un oggetto studente: modificarlo o liberare l'originale non avrà alcun effetto sul clone.

Creerai tre file:

  • student.h: dichiara una struttura Student con due membri: char *name (una stringa allocata dinamicamente) e int grade. Dichiara tre funzioni:
    • create_student: costruttore che riceve un nome e un voto e restituisce un puntatore a un nuovo Student
    • clone_student: riceve un const Student * e restituisce un puntatore a una copia nuova e indipendente
    • free_student: distruttore che libera correttamente tutta la memoria allocata
    Usa le protezioni dalle inclusioni multiple con il simbolo STUDENT_H.
  • student.c: implementa tutte e tre le funzioni. La funzione clone_student è fondamentale. Deve allocare nuova memoria sia per la struttura sia per la stringa del nome, quindi copiare i dati effettivi della stringa (non solo l'indirizzo del puntatore). In questo modo il clone possiede interamente la propria memoria, completamente separata da quella dell'originale.
  • main.c: crea uno studente, clonalo, visualizza le informazioni di entrambi gli studenti, quindi libera correttamente entrambi gli oggetti.

Riceverai due input: il nome dello studente (una stringa) e il voto (un intero).

Nel file principale, crea uno studente con i valori forniti, quindi crea un clone di quello studente. Stampa le informazioni sia dell'originale sia del clone per verificare che contengano gli stessi dati. Infine, libera entrambi gli studenti e stampa una conferma.

Stampa l'output in questo formato:

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

Ad esempio, con gli input Alice e 95, l'output sarebbe:

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

Il modello della copia profonda garantisce che ogni oggetto sia davvero indipendente: il clone ha una propria stringa allocata, non un puntatore condiviso alla memoria dell'originale.

Provalo tu

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

int main() {
    char name[100];
    int grade;
    
    // Leggi l'input
    scanf("%s", name);
    scanf("%d", &grade);
    
    // TODO: Crea uno studente con il nome e il voto forniti
    
    // TODO: Crea un clone dello studente
    
    // TODO: Stampa le informazioni dello studente originale
    // Formato: "Original: {name}, Grade: {grade}"
    
    // TODO: Stampa le informazioni del clone
    // Formato: "Clone: {name}, Grade: {grade}"
    
    // TODO: Libera la memoria di entrambi gli studenti
    
    // Stampa la conferma
    printf("Both freed\n");
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C online