C obsługuje bezpośrednie przypisanie jednej struktury do drugiej tego samego typu: wszystkie pola są kopiowane bajtowo (memcpy). Jest to wygodne do szybkiego klonowania struktury, na przykład:
struct Point { int x, y; }; struct Point p1 = {10, 20}; struct Point p2; p2 = p1; // Teraz p2.x=10, p2.y=20
Cechy:
„Co się stanie, jeśli struktura zawiera wskaźnik na dynamicznie przydzieloną pamięć, a ty przypisujesz jedną strukturę do drugiej?”
Wielu uważa, że całe zawartość zostanie skopiowana, ale tak nie jest.
Odpowiedź: Skopiowana zostanie tylko wartość wskaźnika (adres), a nie dane pod tym adresem. Obie struktury będą wskazywały na tę samą pamięć.
struct Data { int *arr; }; struct Data d1; d1.arr = malloc(10 * sizeof(int)); struct Data d2 = d1; // d2.arr == d1.arr
Zmieniając d2.arr, zmieniasz pamięć widoczną dla d1.arr.
Historia 1
Serializacja danych: przypisali strukturę z wewnętrznym buforem-wskaźnikiem (malloc) — po skopiowaniu dwa różne obiekty wskazywały na tę samą pamięć, a przy zwalnianiu oba wywołały free(). Rezultat — double free i awaria usługi.
Historia 2
W próbie sklonowania złożonej struktury zapomniano wykonać głęboką kopię pól-wskaźników. Po zmianie kopii oczekiwano niezależności, ale zmieniano oryginał (i odwrotnie), tracąc spójność danych.
Historia 3
Przechowywano strukturę z zagnieżdżonym wskaźnikiem na ciąg znaków. Przypisano strukturę, po czym zwolniono jeden z ciągów, a druga struktura nagle "zepsuła się" (dangling pointer), program zaczął zachowywać się nieprzewidywalnie.