W języku C struktury są rozmieszczone niemal dokładnie tak, jak podano w kodzie. Podobne do C# 's StructLayout.Sequential.
Jedyna różnica polega na wyrównaniu elementów. To nigdy nie zmienia kolejności elementów danych w strukturze, ale może zmienić rozmiar struktury poprzez wstawienie bajtów "pad" w środku struktury. Powodem tego jest upewnienie się, że każdy z członków zaczyna na granicy (zwykle 4 lub 8 bajtów).
Na przykład
struct mystruct {
int a;
short int b;
char c;
};
Rozmiary tej struktury jest zazwyczaj 12 bajtów (4 dla każdego użytkownika). Wynika to z faktu, że większość kompilatorów domyślnie sprawia, że każdy członek ma taki sam rozmiar, jak największy w strukturze. Więc char zajmie 4 bajty zamiast jednego. Ale bardzo ważne jest, aby pamiętać, że sizeof (mystruct :: c) będzie nadal o 1, ale sizeof (mystruct) będzie 12.
Może być trudno przewidzieć, w jaki sposób struktura zostanie dopełniona/wyrównana przez kompilator .Większość będzie domyślna, tak jak to wyjaśniłem powyżej, niektóre domyślnie nie będą dopełniać/wyrównywać (również czasami nazywane "spakowanymi").
Metoda zmiany tego zachowania jest zależna od kompilatora, w języku nie ma nic określającego sposób obsługi tego zachowania. W MSVC użyjesz #pragma pack(1)
, aby wyłączyć wyrównanie (1 mówi wyrównać wszystko na 1 granicy bajtów). W GCC użyjesz __attribute__((packed))
w definicji struktury. Zapoznaj się z dokumentacją kompilatora, aby zobaczyć, co robi domyślnie i jak zmienić to zachowanie.
Niektóre kompilatory (tj. GCC) realizują ten sam efekt co '#pragma pack', ale z bardziej szczegółową kontrolą nad semantyką. –
Jestem zaskoczony, widząc upadek. Czy ktoś może wskazać błąd? – Potatoswatter
Dzięki za opiekę. Zaktualizowałem pytanie podczas prowadzenia. – Eonil