Как управлять динамическим массивом строк в C - PullRequest
0 голосов
/ 05 июля 2018

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

struct _recipe
{
    char name[50];
    char** ingredients;
    char diff[12];
    int time;
    int calories;
    char** procedure;   
} recipe;

И я попытался распределить их обоих таким образом

recipe.ingredients = malloc(sizeof(char*) * 50);
recipe.procedure = malloc(sizeof(char*) * 50);

for(i = 0; i < 50; i++)
{
    recipe.ingredients[i] = malloc(sizeof(char) * 30);
    recipe.procedure[i] = malloc(sizeof(char) * 500);
}

Но тогда у меня появляется странный вывод после того, как я пытаюсь написать внутри них. Я отпустил память в конце процесса после того, как распечатал строки, но у меня странное поведение программы, скорее всего, потому что я получаю ошибку сегментации, но я не понимаю, почему на самом деле. Это потому, что я неправильно распределяю память? После того, как я закончил процесс, он говорит, что возвращаемое значение равно 1.

Так я разыменую указатели

for(i = 50; i >= 0; i--){
    free(recipe.ingredients[i]);
}

for(j = 50; j >= 0; j--)
{
    free(recipe.procedure[j]);
}
free(recipe.ingredients);
free(recipe.procedure);

После того, как я попытался установить счетчик, чтобы запомнить, сколько памяти я использовал и освободил только незанятую память, я получил этот вывод

Apple pie
pø└
pø└
P└
P└
P└
PÃ└
PÃ└
PÃ└
PÃ└
└ÿc
└ÿc
└ÿc
pø└
pø└




































Easy
60 min
230 kcal
Mix milk and flour

P└
Bake them

P└
P└
P└
P└
P└
P└
P└
P└
P└
P└
P└
└ÿc
└ÿc
└ÿc

Я знаю, что неправильно разыменовывал с помощью счетчиков, но если я редактировал и разыменовывал все 50 элементов, программа вылетала. В любом случае, чтобы получить этот результат, я поместил это во вход: Название: яблочный пирог Ингредиенты: яблоки сахар Мучной Молоко Сложность: Легко Время в минутах (для приготовления): 60 Калории: 230 Процедура: смешать молоко и муку Добавить яблоки Испечь их И процесс возвращается 1. Я знаю, что это ужасный способ описать рецепт, я просто вставил несколько строк во входные данные, чтобы показать, как он заканчивается

Вот и весь мой код, я не знаю, как избавиться от ошибки

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    struct _recipe
{
    char name[50];
    char** ingredients;
    char diff[12];
    int time;
    int calories;
    char** procedure;   
} recipe;
    int i = 0;
    int j = 0;
    char sentinel[] = "yes";
    char stop[] = "yes";
    char space = '\n';
    int counter = 0;
    int total = 0;
recipe.ingredients = malloc(sizeof(char*) * 50);
recipe.procedure = malloc(sizeof(char*) * 50);

for(i = 0; i < 50; i++)
{
    recipe.ingredients[i] = malloc(sizeof(char) * 30);
    recipe.procedure[i] = malloc(sizeof(char) * 500);
}


        printf("Put the name of recipe:\n");
        fgets(recipe.name,30,stdin);
        do{
            printf("Put the ingredient:\n");
            fgets(recipe.ingredients[j],30,stdin);
            j++;
            counter++;
            printf("Do you want to continue? (yes/no)");
            gets(sentinel);
        } while(strcmp("yes",sentinel) == 0);


        printf("Put difficulty (Easy Medium Hard):\n");
        fgets(recipe.diff,11,stdin);
        printf("Put time for preparation(in minutes):\n");
        scanf("%d", &recipe.time);
        space = getchar();
        printf("Inserisci l'apporto calorico:\n");
        scanf("%d", &recipe.calories);
        space = getchar();
        i = 0;
        do{
            printf("Put the procedure:\n");
            fgets(recipe.procedure[i],1000,stdin);
            i++;
            total++;
            printf("Do you want to continue? (yes/no)\n");
            gets(stop);
        } while(strcmp("yes", stop) == 0);





        printf("%s", recipe.name);
        for(i = 0; i < counter; i++)
        {
            printf("%s", recipe.ingredients[i]);
        }
        printf("%s\n", recipe.diff);
        printf("%d min\n", recipe.time);
        printf("%d kcal\n", recipe.calories);
        for (j = 0; j < total; j++)
        {
            printf("%s", recipe.procedure[j]);
        }

            for(i = 49; i >= 0; i--){
        free(recipe.ingredients[i]);
    }

    for(j = 49; j >= 0; j--)
    {
        free(recipe.procedure[j]);
    }
    free(recipe.ingredients);
    free(recipe.procedure);
    return 0;
}

1 Ответ

0 голосов
/ 05 июля 2018

Ваш код верен, может быть, это способ, которым вы разыменовываете?

Следующие работы:

 for(int i = 0; i < 50; i++)
    {
        for(int j = 0; j < 30; j++){
            recipe.ingredients[i][j] = 'a';
        }
    }
printf("Hello %c", recipe.ingredients[3][4]);

Если вы опубликуете код разыменования, мы поможем вам в дальнейшем.

...