Объявление вектора нулевого размера

Что означает следующее?

struct foo { ... char bar[0]; // Zero size??? }; 

Я спросил своих коллег, и они сказали мне, что это то же самое, что писать void* bar .

Насколько я знаю, C-указатель – это всего лишь 4-байтная переменная (по крайней мере, на 32-битной машине). Как компилятор знает, что bar [0] является указателем (и, следовательно, 4 байта)? Это просто синтаксический сахар?

Ваши коллеги солгали. (Наверное, не намеренно, хотя и не сердитесь на них или что-то еще.)

Это называется гибким элементом массива, а в C99 – char bar[]; , а в C89 – в виде char bar[1]; , и некоторые компиляторы позволят вам писать как char bar[0]; , В основном, вы используете только указатели на структуру и выделяете их все с дополнительным пространством в конце:

 const size_t i = sizeof("Hello, world!"); struct foo *p = malloc(offsetof(struct foo, bar) + i); memcpy(p->bar, "Hello, world!", i); // initialize other members of p printf("%s\n", p->bar); 

Таким образом, p->bar хранит строку, размер которой не ограничен объявлением массива, но который все еще выполняется в том же распределении, что и остальная часть struct (вместо того, чтобы член был char * и необходимость два malloc s и два free s для его настройки).

Ответ Криса правильный, но я бы, вероятно, выделил объект несколько иначе.

 int n = ...; // number of elements you want struct foo *p = malloc(offsetof(struct foo, bar[n])); 

затем перебираем его с помощью

 for (int i = 0; i < n; ++i) { p->bar[i] = ...; } 

Ключевым моментом является то, что ответ Криса работает с sizeof(char)==1 , но для другого типа вам придется явно умножать на sizeof *bar .

Это должна быть ошибка времени компилятора! Только динамически распределенные массивы могут быть выделены с размером 0.

Массив также будет доступен через указатели (индексы являются неявными указателями). Поэтому я подозреваю, что если они скажут вам об этом, это будет интерпретироваться как указатель. Поскольку это массив с нулевой длиной, он, вероятно, укажет на следующее значение (надеюсь, что что-то следует в этой структуре?).

Это недоразумение, а не знание. 🙂

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