У меня есть структура, определенная как:
struct smth
{
char a;
int b[];
};
Когда я звоню sizeof
а также offsetof
на этой структуре:
cout << sizeof(struct smth) << endl;
cout << offsetof(struct smth, b) << endl;
Выход:
4
4
Почему, когда размер элемента равен 4, а символ использует 1 байт, смещение массива int равно 4?
Почему там какая-то набивка?
Кроме того, почему массив int не занимает никакого места вообще?
Почему, когда размер элемента равен 4, а символ использует 1 байт, смещение массива int равно 4? Почему там какая-то набивка?
Есть отступы, потому что стандарт C позволяет это; Компилятор часто выравнивает переменные для повышения производительности.
Кроме того, почему вторая переменная не занимает никакого места вообще (что похоже на случай)?
Это гибкий элемент массива C99 — в этом весь смысл. Идея состоит в том, чтобы выделить вашу структуру примерно так:
struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]);
И тогда у вас будет структура, которая работает как b
были 10-элементный массив.
Потому что размер члена b
равен нулю, и компилятор добавляет отступ между a
а также b
Члены так, что b
находится на границе «слова».
Однако, если я правильно помню, наличие гибкого массива в подобной структуре является допустимым только C, а не C ++, кроме как в качестве расширения компилятора.
Поскольку OP комментирует, что вопрос в C ++:
struct smth
{
char a;
int b[];
};
Массив как b[]
недействителен в C ++. Массив должен иметь фиксированный размер. Массивы переменной длины действительны только в C99.
Предполагая, что ваш компилятор поддерживает его как расширение, массив b[]
имеет нулевой размер, что делает структуру, содержащую только char
член. Правило заполнения в struct
работает, дополняет struct
к слову, которое составляет 4 байта в вашей машине.