Union (unie) to specjalny typ danych, który przechowuje różne wartości w tej samej przestrzeni pamięci. W union wszystkie człony znajdują się w pamięci pod tym samym adresem, a wielkość pamięci odpowiada rozmiarowi największego członu.
Zastosowanie:
Przykład:
union Data { int i; float f; char s[4]; }; union Data d; d.i = 0x41424344; // w pamięci teraz 4 bajty, które można odczytać jako int, float, string printf("%c%c%c ", d.s[0], d.s[1], d.s[2]); // specyficzny dla dostawcy output
Pułapki i zasady użytkowania:
Pytanie: Jaki jest sens używania union, skoro można po prostu użyć struktury z kilkoma polami?
Odpowiedź: Użycie union oszczędza pamięć, ponieważ w danym momencie przechowuje TYLKO JEDNO wartości, a nie wszystkie naraz. W strukturze dla każdego pola przydzielana jest pamięć, a w union — tylko dla największego z pól, pozostałe „dzielą” tę pamięć. Ponadto union pozwala na bezpieczną lub zamierzoną konwersję między różnymi reprezentacjami danych w jednym fragmencie pamięci.
Przykład:
struct S { int i; float f; } s; // sizeof = sizeof(int) + sizeof(float) union U { int i; float f; } u; // sizeof = max(sizeof(int),sizeof(float))
Historia
W projekcie sterownika urządzenia komunikacja z „hardwarem” odbywała się przez union z bitowym dostępem do danych. Po niewielkiej refaktoryzacji programista zaczął pisać do niewłaściwego pola union, co doprowadziło do odczytu nieaktualnych danych i katastrofalnych awarii systemu, ponieważ w union tylko jedno pole było „rzeczywiste” w danym momencie.
Historia
Przy wymianie pakietów sieciowych przez union do zarządzania pamięcią programista zapomniał uwzględnić wyrównanie struktur. W rezultacie wystąpiło przesunięcie o jeden bajt, a struktura była analizowana z niepoprawnymi przesunięciami, co sprawiło, że protokół stał się niekompatybilny z oryginałem.
Historia
W pracy nad biblioteką serializacji programista przekazywał union przez wartość do funkcji, gdzie wymagane pole nie było inicjowane przed odczytem. W związku z tym dane były niepoprawnie serializowane, w wyjściowym strumieniu pojawiał się szum, a przywrócenie początkowych informacji było niemożliwe.