Почему offsetof (member) равен sizeof (struct)?

У меня есть структура, определенная как:

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 не занимает никакого места вообще?

5

Решение

Почему, когда размер элемента равен 4, а символ использует 1 байт, смещение массива int равно 4? Почему там какая-то набивка?

Есть отступы, потому что стандарт C позволяет это; Компилятор часто выравнивает переменные для повышения производительности.

Кроме того, почему вторая переменная не занимает никакого места вообще (что похоже на случай)?

Это гибкий элемент массива C99 — в этом весь смысл. Идея состоит в том, чтобы выделить вашу структуру примерно так:

struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]);

И тогда у вас будет структура, которая работает как b были 10-элементный массив.

8

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

Потому что размер члена b равен нулю, и компилятор добавляет отступ между a а также b Члены так, что b находится на границе «слова».

Однако, если я правильно помню, наличие гибкого массива в подобной структуре является допустимым только C, а не C ++, кроме как в качестве расширения компилятора.

3

Поскольку OP комментирует, что вопрос в C ++:

struct smth
{
char a;
int b[];
};

Массив как b[] недействителен в C ++. Массив должен иметь фиксированный размер. Массивы переменной длины действительны только в C99.

Предполагая, что ваш компилятор поддерживает его как расширение, массив b[] имеет нулевой размер, что делает структуру, содержащую только char член. Правило заполнения в struct работает, дополняет struct к слову, которое составляет 4 байта в вашей машине.

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