Динамическое выделение C 2-мерного массива

#c #multidimensional-array #struct #declaration #dynamic-memory-allocation

#c #многомерный массив #структура #объявление #динамическое выделение памяти

Вопрос:

 struct Cases
    {
        int number;
        char *name[][20];
    };
  

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

 int main()
    {
        struct Cases Real;
    
        Real.name = malloc(3 * sizeof(char));
        if (Real.name == NULL) {
            fprintf(stderr, "Malloc failed.n");
            exit(1);
        }
.
.
.
  

Комментарии:

1. char *name[][20] — это массив массивов массивов символов. Это массив массивов строк. Это массив абзацев. Что это должно name символизировать? У кого-нибудь есть массив массивов имен? Что вы пытаетесь смоделировать?

2. name является гибким элементом массива (поскольку его внешний размер не указан), а не указателем, поэтому вы не можете назначить ему. И это не a char * , поэтому 3 * sizeof(char) не даст полезного размера.

3. Кажется, вы смешиваете гибкий элемент массива и общие указатели. Пожалуйста, решите, чего вы хотите.

4. @KamilCuk я получу названия городов от пользователя и сохраню их в массиве, но размер будет постоянно меняться, поэтому я не могу определить его с самого начала. Я должен выделять его каждый раз.

5. @user253751: char *name[][20] объявляет массив массивов из 20 указателей на char . Чтобы объявить указатель на массив array of char , он должен быть char (*name)[][20] .

Ответ №1:

Это объявление

 char *name[][20];
  

объявляет массив с неизвестным размером.

Это объявление структуры

 struct Cases
{
    int number;
    char *name[][20];
};
  

объявляет структуру с гибким элементом массива.

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

 Real.name = malloc(3 * sizeof(char));
  

Более того, вызов malloc не имеет смысла.

Но, похоже, вы имеете в виду объявление указателя вместо массива. То есть структура должна выглядеть так

 struct Cases
{
    int number;
    char ( *name )[20];
};
  

Если вы хотите выделить массив из 3 «строк», тогда вам следует написать

 Real.name = malloc(3 * sizeof(char[20]));
  

Если вы хотите объявить массив указателей на строковые литералы, то объявление структуры может выглядеть следующим образом

 struct Cases
{
    int number;
    char **name;
};
  

В этом случае вы можете выделить память следующим образом

 Real.name = malloc( 3 * sizeof( char * ) );
  

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

 Real.name[0] = "test";
  

Комментарии:

1. Допустим, элементами имени являются {‘test’, ‘test’, ‘test’} , здесь он состоит из 3 элементов. Каждый раз, когда вводится новое имя, размер должен увеличиваться на единицу. Вот почему я использую указатели на выделение памяти позже.

2. хорошо, я понял, большое спасибо, еще один вопрос, если попытаться получить такое имя scanf("%s", amp;Real.name[0]); , будет ли оно работать?

3. @Carl Это может работать для первого объявления элемента данных, а не для второго.

4. Да, я только что попробовал, но программа вылетает, есть идеи, как мне получить данные?

5. @Carl Вот демонстрационная программа, которая отлично работает. #включить <stdio.h> #включить <stdlib.h> структурные случаи {int number; char ( *name )[20]; }; int main(void) { структурные случаи Real = { 3, NULL }; Real.name = malloc( реальное число * sizeof(символ[20])); scanf(«s», Real.name [0] ); ставит( Real.name [0] ); возвращает 0; }