Il C supporta l'assegnazione diretta di una struttura a un'altra di stesso tipo: tutti i campi vengono copiati byte per byte (memcpy). Questo è utile per clonare rapidamente una struttura, ad esempio:
struct Point { int x, y; }; struct Point p1 = {10, 20}; struct Point p2; p2 = p1; // Ora p2.x=10, p2.y=20
Caratteristiche:
"Cosa succede se la struttura contiene un puntatore a memoria allocata dinamicamente e si assegna una struttura all'altra?"
Molti pensano che venga coperto tutto il contenuto, ma non è così.
Risposta: Viene copiato solo il valore del puntatore (l'indirizzo), non i dati a quell'indirizzo. Entrambi gli oggetti della struttura si riferiranno alla stessa memoria.
struct Data { int *arr; }; struct Data d1; d1.arr = malloc(10 * sizeof(int)); struct Data d2 = d1; // d2.arr == d1.arr
Modificando d2.arr, si modifica la memoria visibile a d1.arr.
Storia 1
Serializzazione dei dati: assegnata una struttura con un buffer interno puntatore (malloc) — dopo la copia, due oggetti diversi puntavano alla stessa memoria, e al momento del rilascio entrambi chiamavano free(). Risultato — double free e crash del servizio.
Storia 2
Nel tentativo di clonare una struttura complessa, ho dimenticato di fare una copia profonda dei campi dei puntatori. Dopo aver modificato la copia ci si aspettava indipendenza, ma si modificava l'originale (e viceversa), perdendo la coerenza dei dati.
Storia 3
Conservavo una struttura con un puntatore annidato a una stringa. Ho assegnato la struttura, dopo di che ho liberato una delle stringhe, e l'altra struttura improvvisamente si è "rotta" (dangling pointer), il programma ha iniziato a comportarsi in modo imprevedibile.