Почему размер класса зависит от порядка объявления членов? и как?

Кто-то объяснит мне, как порядок объявления членов внутри класса определяет размер этого класса.

Например :

class temp
{
public:
int i;
short s;
char c;
};

Размер вышеприведенного класса составляет 8 байт.

Но когда порядок декларации члена изменяется, как показано ниже

class temp
{
public:
char c;
int i;
short s;
};

тогда размер класса составляет 12 байтов.

Как?

20

Решение

Причиной вышеупомянутого поведения является выравнивание и заполнение структуры данных. В основном, если вы создаете 4-байтовую переменную, например, int, он будет выровнен по четырехбайтовая граница, т.е. она будет начинаться с адреса в памяти, кратного 4. То же относится и к другим типам данных. 2 байта должны начинаться с четного адреса памяти и так далее.

Следовательно, если у вас есть 1-байтовый символ, объявленный перед int (предположим, 4 байта здесь), между ними останется 3 свободных байта. Общий термин, используемый для них — «дополненный».

Выравнивание структуры данных

Еще одно хорошее наглядное объяснение

Причина выравнивания

Заполнение обеспечивает более быстрый доступ к памяти, то есть для процессора, доступ к областям памяти, которые выровнены, быстрее, например. чтение 4-байтового выровненного целого числа может занять один вызов для чтения где, как будто целое число находится в невыровненном диапазоне адресов (скажем, адрес 0x0002 — 0x0006), тогда потребуется два чтения памяти чтобы получить это целое число.

Один из способов заставить компилятор избегать выравнивания (специфично для gcc / g ++) — использовать ключевое слово ‘уплотненный‘с атрибутом структуры. упакованное ключевое слово Также ссылка указывает, как обеспечить выравнивание по определенной границе по вашему выбору (2, 4, 8 и т. Д.), Используя выровненный ключевое слово.

Лучшая практика

Это всегда хорошая идея структурировать ваш класс / структуру таким образом, чтобы переменные уже были выровнены с минимальным заполнением. Это уменьшает размер класса в целом, а также уменьшает объем работы, выполняемой компилятором, т. Е. Нет перестройки структуры. Также следует всегда обращаться к переменным-членам по их именам в коде, а не пытаться читать конкретный байт из структуры, предполагая, что значение будет находиться в этом байте.

Еще один полезный ТАК вопрос о производительности преимущество выравнивания

Для завершения следую до сих пор имеют размер 8 байт в вашем сценарии (32-битная машина), но лучше не станет полные 8 байтов теперь заняты, и там нет отступов.

class temp
{
public:
int i;
short s;
char c;
char c2;
};
36

Другие решения

class temp
{
public:
int i;   //size 4 alignment 4
short s; //size 2 alignment 2
char c;  //size 1 alignment 1
}; //Size 8 alignment max(4,2,1)=4

темп [я[0-4];s[4-2];с[6-7]]] -> 8
Заполнение в (7-8)

class temp
{
public:
char c;  //size 1 alignment 1
int i;   //size 4 alignment 4
short s; //size 2 alignment 2
};//Size 12 alignment max(4,2,1)=4

темп [с[0-1];я[4-8];s[8-10]]] -> 12
Отступы в (1-4) и (10-12)

1

По вопросам рекламы [email protected]