Zanim odpowiem, chciałbym podać kilka danych z Wiki
Wyrównanie struktury danych to sposób organizowania danych i uzyskiwania do nich dostępu w pamięci komputera. Składa się z dwóch oddzielnych, ale powiązanych zagadnień: wyrównania danych i wypełnienia struktury danych .
Kiedy nowoczesny komputer czyta lub zapisuje na adres pamięci, robi to w fragmentach wielkości słowa (np. 4-bajtowe fragmenty w systemie 32-bitowym). Dopasowanie danych oznacza umieszczenie danych w przesunięciu pamięci równym pewnej wielokrotności rozmiaru słowa, co zwiększa wydajność systemu ze względu na sposób, w jaki procesor obsługuje pamięć.
Aby wyrównać dane, może być konieczne wstawienie kilku bezsensownych bajtów między końcem ostatniej struktury danych a początkiem następnej, czyli wypełnienia struktury danych .
gcc zapewnia funkcję wyłączania dopełniania struktury. tj. aby w niektórych przypadkach uniknąć tych bezsensownych bajtów. Rozważ następującą strukturę:
typedef struct
{
char Data1;
int Data2;
unsigned short Data3;
char Data4;
}sSampleStruct;
sizeof(sSampleStruct)
będzie 12 zamiast 8. Z powodu wypełnienia struktury. Domyślnie w X86 struktury będą dopełniane do 4-bajtowego wyrównania:
typedef struct
{
char Data1;
//3-Bytes Added here.
int Data2;
unsigned short Data3;
char Data4;
//1-byte Added here.
}sSampleStruct;
Możemy użyć, __attribute__((packed, aligned(X)))
aby nalegać na wypełnienie o określonym rozmiarze (X). X powinno być potęgą dwójki. Zobacz tutaj
typedef struct
{
char Data1;
int Data2;
unsigned short Data3;
char Data4;
}__attribute__((packed, aligned(1))) sSampleStruct;
więc wyżej określony atrybut gcc nie pozwala na wypełnienie struktury. więc rozmiar będzie wynosił 8 bajtów.
Jeśli chcesz zrobić to samo dla wszystkich struktur, po prostu możemy przesunąć wartość wyrównania do stosu za pomocą #pragma
#pragma pack(push, 1)
//Structure 1
......
//Structure 2
......
#pragma pack(pop)