programowanieBackend C developer

Opisz cechy pracy z operacją przypisania struktur w języku C. Jak kopiowane są struktury, jakie są zalety i ograniczenia, jakie błędy mogą wystąpić?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

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:

  • Wszystkie pola są kopiowane „jak jest” (bit po bicie).
  • Jeśli pola to wskaźniki/tablice, kopiowany jest tylko sam wskaźnik, a nie zawartość pod tym adresem (głębokie kopiowanie nie zachodzi!).
  • Przypisanie działa tylko dla struktur tego samego typu.

Pytanie podchwytliwe

„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.

Przykłady rzeczywistych błędów z powodu niewiedzy o szczegółach tematu


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.