Возможно ли установить размер массива внутри структуры во время выполнения?
У меня есть структура, как показано ниже:
struct Query {
int pages[];
int currentpage;
};
Мне было интересно, можно ли установить размер этого массива после создания структуры.
Query new = malloc(sizeof(struct Query));
После этого, я буду выполнять некоторые вычисления, которые затем скажут мне размер, который должен быть pages[]
. Если pages[]
должен быть размером 4, как я могу установить его как таковой?
Ответы
Ответ 1
Измените тип элемента pages
на указатель.
struct Query {
int *pages;
int currentpage;
};
struct Query *test = malloc(sizeof(struct Query));
if (test != NULL)
{
//your calculations
test->pages = malloc(result_of_your_calcs);
if (test->pages != NULL)
{
// YOUR STUFF
}
else
{
// ERROR
}
}
else
{
// ERROR
}
Когда вы free
свою структуру, вы должны сделать это наоборот.
free(test->pages);
free(test);
Ответ 2
В C99 вы можете использовать Гибкие элементы массива:
struct Query {
int currentpage;
int pages[]; /* Must be the last member */
};
struct Query *new = malloc(sizeof(struct Query) + sizeof(int) * 4);
Ответ 3
Вы можете использовать элемент Гибкий массив (подробнее в @AlterMann answer) (C99 +) или массив Нулевая длина ( GNU C).
Цитата из https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html,
В GNU C. допустимы массивы нулевой длины. Они очень полезны в качестве последнего элемента структуры, который действительно является заголовком для объекта переменной длины:
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
Для стандартного C90 связанный сайт упоминает
В ISO C90 вам нужно указать contents
длину 1, что означает либо свободное пространство, либо сложность аргумента malloc
.
Это означает, что для того, чтобы код работал в стандартном C90/C89, char contents[0];
должен быть char contents[1];
.
Ответ 4
Лучшим решением было бы использовать указатели на int
вместо массива.
Вам нужно будет изменить:
int pages[];
to:
int *pages;
а затем динамически распределите его следующим образом:
Query *new = malloc(sizeof(struct Query));
if (new == NULL)
printf ("Error\n");
else
{
new->pages = malloc(4*sizeof(int));
if (new->pages == NULL)
printf ("Error\n");
}
В противном случае, если вы хотите сохранить свой формат, вы будете использовать режим C99. Объявите pages
в качестве последнего члена вашей структуры, например:
struct Query {
int currentpage;
int pages[];
};
а затем выполните:
Query *new = malloc(sizeof(struct Query) + 4*sizeof(int));
Ответ 5
Объявите его как указатель и используйте malloc
после
struct Query {
int * pages;
int currentpage;
};
. . .
struct Query obj;
obj.pages = malloc(n * sizeof(int)); // n is the length you want