Как выровнять структуру или класс размером 20 байт или другим размером не-степени-два?
Выравнивание зависит от процессора, поэтому ответа нетна этот вопрос, по крайней мере, без знания целевого процессора.
Вообще говоря, выравнивание - это не то, о чем вам нужно беспокоиться;у вашего компилятора будут реализованы правила для вас.Это происходит время от времени, как при написании распределителя.Классическое решение обсуждается в Языке программирования C (K & R): используйте наихудшее выравнивание.malloc
делает это, хотя он формулируется как , «указатель, возвращаемый в случае успешного выделения, должен быть соответствующим образом выровнен, чтобы его можно было назначить указателю на любой тип объекта».
Способ сделать , что - это использовать union
(все элементы union
размещаются по базовому адресу union
, и поэтому union
должны быть выровнены втаким образом, что каждый элемент может существовать по этому адресу, т. е. выравнивание union
будет таким же, как выравнивание элемента с самыми строгими правилами):
typedef Align long;
union header {
// the inner struct has the important bookeeping info
struct {
unsigned size;
header* next;
} s;
// the align member only exists to make sure header_t's are always allocated
// using the alignment of a long, which is probably the worst alignment
// for the target architecture ("worst" == "strictest," something that meets
// the worst alignment will also meet all better alignment requirements)
Align align;
};
Память выделяетсясоздание массива (используя что-то вроде sbrk()
) размером header
s, достаточно большого для удовлетворения запроса, плюс один дополнительный элемент header
, который фактически содержит бухгалтерскую информацию.Если массив называется arry
, бухгалтерская информация находится на arry[0]
, в то время как возвращаемый указатель указывает на arry[1]
(элемент next
предназначен для обхода свободного списка).
Это работает, но может привести к потере впустую пространства («В JSM Sun HotSpot хранилище объектов выравнивается по ближайшей 64-битной границе»).Мне известен лучший подход , который пытается получить выравнивание, специфичное для типа, а не "выравнивание, которое будет работать для чего-либо".
Компиляторы также часто имеют команды, специфичные для компилятора.Они не являются стандартными и требуют, чтобы вы знали правильные требования к выравниванию для рассматриваемых типов.Я бы их избегал.