Объявление нулевого размера вектора - PullRequest
4 голосов
/ 23 ноября 2010

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

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

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

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

Ответы [ 4 ]

5 голосов
/ 23 ноября 2010

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

Это называется членом гибкого массива, а в 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).

3 голосов
/ 23 ноября 2010

Крис ответил правильно, но я бы, вероятно, выделил объект немного по-другому.

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 голосов
/ 23 ноября 2010

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

Это подозрение, а не знание.:)

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

0 голосов
/ 23 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...