Как узнать размер структуры?

struct a
{
    char *c;
    char b;
};

Что такое sizeof (а)?


person Community    schedule 27.09.2008    source источник
comment
sizeof (a) недействителен C. Тем не менее, он будет действителен в C ++.   -  person alk    schedule 30.07.2017


Ответы (8)


#include <stdio.h>

typedef struct { char* c; char b; } a;

int main()
{
    printf("sizeof(a) == %d", sizeof(a));
}

Я получаю "sizeof (a) == 8" на 32-битной машине. Общий размер структуры будет зависеть от упаковки: в моем случае упаковка по умолчанию равна 4, поэтому 'c' занимает 4 байта, 'b' занимает один байт, оставляя 3 байта заполнения, чтобы довести его до следующего кратного 4 байта. : 8. Если вы хотите изменить эту упаковку, у большинства компиляторов есть способ изменить ее, например, на MSVC:

#pragma pack(1)
typedef struct { char* c; char b; } a;

дает sizeof (a) == 5. Если вы это сделаете, будьте осторожны, чтобы сбросить упаковку перед любыми заголовками библиотеки!

person Simon Buchan    schedule 27.09.2008
comment
Чтобы убедиться, что это работает: printf (sizeof (a) ==% d, (int) sizeof (a)); ´ - person Thomas Padron-McCarthy; 05.10.2008
comment
@ ThomasPadron-McCarthy Скорее _1 _... - person ; 14.08.2013
comment
@ H2CO3: Да, это тоже работает в достаточно современном C. - person Thomas Padron-McCarthy; 15.08.2013
comment
2008 год мне действительно дурацкий. Во-первых, 5 лет назад у меня была 32-битная машина? А то про размер параметра забыл в вопросе про разрядность? Хорошо, что в следующем ответе есть некоторые подробности. - person Simon Buchan; 20.08.2013

Вопреки тому, что было сказано в некоторых других ответах, в большинстве систем при отсутствии прагмы или параметра компилятора размер структуры будет не менее 6 байтов, а в большинстве 32-битных систем - 8 байтов. Для 64-битных систем размер может легко составить 16 байт. Согласованность действительно вступает в игру; всегда. Размер одной структуры должен быть таким, чтобы можно было выделить массив этих размеров, а отдельные элементы массива были достаточно выровнены для рассматриваемого процессора. Следовательно, если размер структуры был 5, как предполагали другие, то массив из двух таких структур будет иметь длину 10 байт, а указатель char во втором члене массива будет выровнен по нечетному байту, что (в большинстве процессоры) являются серьезным узким местом в производительности.

person Jonathan Leffler    schedule 27.09.2008
comment
А на старых 68k Mac - сбой! - person Simon Buchan; 27.09.2008
comment
Причина, по которой я предположил, что выравнивание не будет иметь никакого эффекта, заключается в том, что оба члена будут правильно выровнены без отступов между ними. Я не ожидал, что sizeof будет учитывать отступы в конце. Моя гипотеза была опровергнута экспериментально, как я отметил в редакции моего ответа. - person Fred Larson; 27.09.2008

Если вы хотите подсчитать его вручную, размер структуры - это просто размер каждого из ее элементов данных после учета выравнивания. Для структуры нет магических служебных байтов.

person Jeff Hubbard    schedule 27.09.2008

Точное значение - sizeof (a).
Вы также можете рискнуть и предположить, что в данном случае оно не меньше 2 и не больше 16.

person eugensk    schedule 27.09.2008
comment
Хотя теоретически верхнего предела нет, поскольку реализация и размер указателей зависят от компилятора, при условии, что они ведут себя в соответствии со стандартом. - person Skizz; 18.02.2009

Это будет зависеть от вашей архитектуры и того, как она обрабатывает основные типы данных. Это также будет зависеть от того, требует ли система естественного выравнивания.

person mdec    schedule 27.09.2008

Я предполагаю, что вы имеете в виду структуру, а не строгую, но в 32-битной системе это будет либо 5, либо 8 байтов, в зависимости от того, дополняет ли компилятор структуру.

person Serafina Brocious    schedule 27.09.2008

Я подозреваю, что вы имели в виду «структура», а не «строгий», и «char» вместо «Char».

Размер будет зависеть от реализации. В большинстве 32-битных систем это, вероятно, будет 5–4 байта для указателя, один для символа. Я не верю, что здесь в игру вступит согласованность. Однако если вы поменяли местами «c» и «b», размер может вырасти до 8 байт.

Хорошо, я попробовал (g ++ 4.2.3, с параметром -g) и получил 8.

person Fred Larson    schedule 27.09.2008
comment
выравнивание может вступить в игру. - person jop; 27.09.2008

Размер структуры должен быть 8 байтов в 32-битной системе, чтобы размер структуры стал кратным 2. Это делает отдельные структуры доступными на правильных границах байтов, когда объявляется массив структур. Это достигается за счет заполнения структуры 3 байтами в конце.

Если бы в структуре был указатель, объявленный после символа, она все равно имела бы размер 8 байтов, но было бы добавлено 3-байтовое заполнение, чтобы указатель (который является 4-байтовым элементом) выровнялся по границе 4-байтового адреса.

Эмпирическое правило состоит в том, что элементы должны иметь смещение, кратное их размеру в байтах, а сама структура должна иметь размер, кратный 2.

person computinglife    schedule 27.09.2008
comment
Это относительно редко, но структура, содержащая только массивы символов, может иметь нечетный размер: struct unusual { char a[3]; char b[4]; }; может иметь размер 7, не вызывая каких-либо негативных последствий. Компилятор может дополнить его до 8 байтов, но в этом нет очевидной необходимости. - person Jonathan Leffler; 07.06.2015