Выделение размера массива внутри структуры из пользовательского ввода в C - PullRequest
0 голосов
/ 01 сентября 2018

Я недавно работаю над проектом на C. У меня есть требование выделить массив внутри структуры, и его размер должен быть получен от пользователя. Но из-за особых требований я не могу использовать указатели, а затем выделять память с помощью malloc.

Мой код выглядит следующим образом:

#define arraySize size

typedef struct sample{
    int keys[arraySize]
    int pointers[arraySize + 1]
} sample;

int main(){
   //size should be obtained from user input
   size  = 15;
}

Если структура определена внутри main, она работает нормально, но проблема в том, что структура не будет глобальной. Если я объявляю структуру, как указано в коде, она выдает сообщение об ошибке, в котором говорится, что размер массива должен быть постоянным. Кто-нибудь может мне помочь с этим вопросом?

1 Ответ

0 голосов
/ 01 сентября 2018

(просто приведу примеры для комментариев.)

Я думаю, что есть несколько типичных способов обработки вашего сценария:


Метод 1: Глобальный указатель на ресурсы, выделенные в стеке main (уже предложено в других комментариях):

Этот вариант использует функцию C99 / расширение GCC (w.r.t C89) для изменяемых типов / изменяемых массивов, согласно комментарию Джонатана Леффлера.

 struct sample *globalSample = NULL;
 int main(){
    //size should be obtained from user input
    size  = 15;

    struct sample{
        int keys[size];
        int pointers[size + 1];
    } mySample;
    globalSample = &mySample;
 }

В этом варианте используются alloca и «член гибкого массива». В приведенном ниже комментарии Джонатана Леффлера отмечается изменение официально определенного синтаксиса для этого между C89 и более поздними версиями спецификации C.

 struct inner {
     int key;
     int pointer;
 };
 struct sample {
     unsigned int num_allocated;
     struct inner members[1]; // struct hack
 };

 struct sample *globalSample = NULL;
 int main(){
    //size should be obtained from user input
    size  = 15;

    globalSample = alloca((size+1) * sizeof(struct sample));
    globalSample->num_allocated = size;  /*just for book-keeping*/

    globalSample->members[0].key = /*...*/;
    globalSample->members[0].pointer = /*...*/;
    globalSample->members[1].key = /*...  reaching past declared size */
    globalSample->members[1].pointer = /*...*/;

 }

Метод 2: Определите максимальный размер и подтвердите введенные пользователем данные.

 #define MAX_ENTRIES 4096
 struct sample{
     int keys[MAX_ENTRIES];
     int pointers[MAX_ENTRIES + 1];
 } globalSample;

 int main(){
    //size should be obtained from user input
    size  = 15;

    if(MAX_ENTRIES < size) { /* error case */ }

 }
...