Размер структуры с двумя пустыми указателями равен 4? - PullRequest
6 голосов
/ 16 сентября 2010

Я не понимаю, почему

struct e{
    void * a;
    void * b[];
}

имеет sizeof (e) == 4, а

struct f{
    void * a;
    void * b;
}

имеет sizeof (f) == 8.

Ответы [ 5 ]

17 голосов
/ 16 сентября 2010
struct e{
    void * a;
    void * b[];
//          ^^
}

[] в структуре делает b гибким элементом массива C99.Таким образом, sizeof(e) будет считать только размер a, который равен 4.

. Из C99 §6.7.2.1 / 16:

В качестве особого случая последний элементструктуры с более чем одним именованным членом может иметь тип неполного массива;это называется гибкий элемент массива .В большинстве случаев член гибкого массива игнорируется. В частности, размер структуры такой, как если бы элемент гибкого массива был опущен , за исключением того, что он может иметь больше завершающего дополнения, чем подразумевает пропущение.

Однако, когда у оператора . (или ->) есть левый операнд, который является (указателем) на структуру с элементом гибкого массива, и правый операнд называет этот член, он ведет себя так, как если быэтот элемент был заменен самым длинным массивом (с тем же типом элемента), который не сделал бы структуру больше, чем объект, к которому осуществляется доступ;смещение массива должно оставаться смещением элемента гибкого массива, даже если оно будет отличаться от смещения массива замены.Если в этом массиве нет элементов, он ведет себя так, как если бы у него был один элемент, но поведение не определено, если предпринята какая-либо попытка получить доступ к этому элементу или сгенерировать указатель после него.

12 голосов
/ 16 сентября 2010

Вторым в первой структуре является не указатель, а FAM - гибкий элемент массива.Он используется, когда у вас длинный буфер и вы ставите e в начале этого буфера.Затем вы можете индексировать оставшуюся память, которая следует за объектом e, используя эту FAM и обрабатывать эту память как массив void*.

Стандарт гласит (выделено мной)

В особом случае последний элемент структуры с более чем одним именованным элементом может иметь тип неполного массива;это называется членом гибкого массива.В большинстве случаев член гибкого массива игнорируется. В частности, размер структуры такой, как если бы элемент гибкого массива был опущен, за исключением того, что он может иметь больше запаздывающего отступа, чем это может означать упущение.следующий код выводит 1 для структуры без, но 4 для структуры с FAM на GCC, потому что для доступа к целым числам FAM необходимо правильно выровнять (на 4-байтовой границе в этом примере)*

2 голосов
/ 16 сентября 2010

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

1 голос
/ 16 сентября 2010

void * b[]; недопустимо в C89, поэтому это означает, что вы используете C99 компилятор.

C99 представил средство для определения "struct hack": теперь это называетсягибкий элемент массива "и до того, как ему выделена память, его размер равен 0.

0 голосов
/ 16 сентября 2010

Потому что первая не объявляет место для указателей в "b".

...