Ответ 1
Прежде чем ответить, я хотел бы дать вам некоторые данные из Вики
Выравнивание структуры данных - это способ упорядочения и доступа к данным в памяти компьютера. Он состоит из двух отдельных, но связанных вопросов: выравнивание данных и заполнение структуры данных.
Когда современный компьютер выполняет чтение или запись по адресу памяти, он будет делать это в виде кусочков (например, 4-байтных кусков в 32-разрядной системе). Выравнивание данных означает размещение данных со смещением памяти, равным некоторому кратному размеру слова, что повышает производительность системы благодаря тому, как процессор обрабатывает память.
Для выравнивания данных может потребоваться вставить несколько бессмысленных байтов между концом последней структуры данных и началом следующей, то есть заполнение структуры данных.
gcc предоставляет функциональность для отключения заполнения структуры. то есть, чтобы избежать этих бессмысленных байтов в некоторых случаях. Рассмотрим следующую структуру:
typedef struct
{
char Data1;
int Data2;
unsigned short Data3;
char Data4;
}sSampleStruct;
sizeof(sSampleStruct)
будет 12, а не 8. Из-за заполнения структуры. По умолчанию в X86 структуры будут дополнены 4-байтовым выравниванием:
typedef struct
{
char Data1;
//3-Bytes Added here.
int Data2;
unsigned short Data3;
char Data4;
//1-byte Added here.
}sSampleStruct;
Мы можем использовать __attribute__((packed, aligned(X)))
, чтобы настаивать на заполнении определенного (X) размера. Х должен быть степенью двойки. См. здесь.
typedef struct
{
char Data1;
int Data2;
unsigned short Data3;
char Data4;
}__attribute__((packed, aligned(1))) sSampleStruct;
поэтому указанный выше атрибут gcc не допускает заполнение структуры. поэтому размер будет 8 байтов.
Если вы хотите сделать то же самое для всех структур, просто мы можем поместить значение выравнивания в стек, используя #pragma
#pragma pack(push, 1)
//Structure 1
......
//Structure 2
......
#pragma pack(pop)