Как создать структуру с динамически изменяемым размером в нем в C - PullRequest
3 голосов
/ 19 марта 2019

Учитывая, что у меня есть структура что-то вроде этого:

struct arr {
  int len;
  void *item[]; // still playing with this
};

typedef struct arr my_array;

Мне интересно, как вы его инициализируете.

my_array foo = { 0, 1000 }; // 1000 spaces reserved.
// or perhaps...
my_array foo = { 0, [1000] };

Потому что, когда у вас естьобычный массив, вы указываете размер следующим образом:

int anarray[1000];

Так что я подумал, что вы могли бы сделать это для инициализации значения указателя в структуре массива выше.

Может быть, даже

foo->item[1000];

Я не знаю.Интересно, возможно ли что-нибудь подобное?

Ответы [ 3 ]

3 голосов
/ 19 марта 2019

Гибкие члены массива действительно полезны только при динамическом размещении структуры. Если структура выделяется статически или автоматически (то есть в стеке), объем выделенной памяти равен sizeof(struct arr), который рассчитывается с 0 элементами в item. Нет синтаксиса для определения переменной, тип которой является структурой с элементом гибкого массива, и для указания размера этого массива.

Итак, если вы разместите эту структуру в стеке, это все, что нужно сделать:

struct my_array foo = { 0 };

Чтобы поместить элементы в гибкий массив, необходимо динамически распределять память.

struct my_array *foo = malloc(sizeof(*foo) + 1000 * sizeof(foo->item[0]));
2 голосов
/ 19 марта 2019

A struct тип с гибким элементом массива необходимо динамически размещать, если вы хотите, чтобы массиву было выделено для него пространство:

struct arr *foo = malloc( sizeof *foo + (sizeof foo->item[0] * 1000) );
if ( foo )
{
  foo->len = 1000;
  for ( int i = 0; i < foo->len; i++ )
    foo->item[i] = some_value();
}
...
free( foo );
0 голосов
/ 19 марта 2019

Предположим, что вы хотите, чтобы item элемент гибкого массива содержал m указатели,

struct arr *p = malloc(sizeof (struct arr) + sizeof ((void*)[m])); 

Это будет вести себя так, как вы определили структуру как

struct arr {
  int len;
  void *item[m];
};

Объявлениеон неполный, он позволяет вам выбрать во время выполнения размер массива.

In 6.7.2.1 Structure and union specifiers, p16:

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

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