При использовании структур, включающих поля различных типов, следует быть очень внимательным и четко осознавать, как структура будет располагаться в памяти. В противном случае это может привести к трудновыявляемым ошибкам.

Предположим, объявлена такая структура:

struct bug_t {

int a;

long long b;

int c;

};

Размер структуры: sizeof(struct bug_t) = 24 байта, причем sizeof(int)=4, sizeof(long long) = 8. Итого должно быть 16. Как же получается 24?

А получается, что 8 байт уходят на выравнивание. В памяти структура будет располагаться следующим образом:

1) Поле "а" (4 байта)

2) 4 байта дополнения (!). Они необходимы для выравнивания следующего 8-байтового поля.

3) 8 байт поля "b" (long long)

4) 4 байта поля "с"

5) 4 байта дополнения (!). А зачем же нужны эти 4 байта? Все дело в том, что выравнивание структуры должно быть равно выравниванию ее максимального элемента, т.е. long long.

Для того, чтобы память не тратилась на выравнивание можно, например, переставить элементы в структуре местами:

struct bug_t {

int a;

int c;

long long b;

};

В этом случае все элементы будут располагаться в памяти подряд.

В заключение следует заметить, что подобным образом выравнивание будет выполняться не для всех процессоров (но для MIPS и PowerPC это так) и компиляторов. Во многих компиляторах есть специальные опции компиляции и макросы #pragma, позволяющие управлять выравниванием.

Последнее изменение: Понедельник, 5 сентября 2011, 12:30