函数在第一次调用时会正确分配内存,但在第二次调用时不会正确分配内存

时间:2019-12-22 09:42:39

标签: c

我必须从控制台读取“数据库”。输入的结构如下:

[nr of food types]
food_type_1:[nr of food types for food type 1]
(food_subtype_1 - [price]) (food_subtype_2 - [price]) etc.
food_type_2:[nr of food types for food type 2]
(food_subtype_1 - [price]) (food_subtype_2 - [price]) etc.
[nr of drinks]
(drink_1 - [price]) (drink_2 - [price]) etc.

例如,输入内容可能是:

2
Pizza:2
(Pizza Margherita - 23) (Pizza Con Pollo - 25)
Pasta:1
(Pasta Carbonara - 22)
3
(Coca Cola - 4) (Tea - 5) (Water - 2)

为此,我使用了一些结构:

typedef struct _food {
    char* name;
    int nrOfSubtypes;
    foodSubtype* subtypes;
} food;

typedef struct _foodSubtype {
    char* name;
    double price;
} foodSubtype;

对于每种结构类型,我都有一些函数可以为指针动态分配内存:

food createFood(int nrSubtypes) {
    food f;
    f.name = (char*) malloc(WORD_LENGTH* sizeof(char));
    f.nrOfSubtypes = nrSubtypes;
    f.subtypes = (foodSubtype*) malloc(f.nrOfSubtypes* sizeof(foodSubtype));
    for (int i = 0; i < f.nrOfSubtypes; ++i) {
        f.subtypes[i] = createSubtype();
    }
    return f;
}

foodSubtype createSubtype() {
    foodSubtype f;
    f.name = (char*) malloc(WORD_LENGTH* sizeof(char));
    f.price = 0;
    return f;
}

现在,在阅读功能中,我逐行获取输入,然后通过用strtok分隔输入来解析输入。使用的功能之一是parseFoodName,它将我刚刚读取的行输入和指向food变量的指针作为参数:

void parseFoodName(char *string, food *f) {
    char* name = (char*) malloc(WORD_LENGTH* sizeof(char));
    int nr;
    strcpy(name, strtok(string, ":"));
    string = strtok(NULL, "");
    nr = atoi(string);
    *f = createFood(nr);
    strcpy(f->name, name);
}

parseFoodNameloadDataFromConsole中的调用如下:

void loadDataFromConsole(int *nrOfFoodsAddr, food **foodsAddr) {
    printf("%s", INPUT_DATA_MSG);
    scanf("%d", nrOfFoodsAddr);
    getchar();
    *foodsAddr = (food*) malloc((*nrOfFoodsAddr+1)* sizeof(food));
    char *inputLine;
    inputLine = (char*) malloc(INPUT_LINE_LENGTH* sizeof(char));
    for (int i = 0; i < *nrOfFoodsAddr; ++i) {
        gets(inputLine);
        parseFoodName(inputLine, foodsAddr[i]);
        gets(inputLine);
        parseSubtypes(inputLine, foodsAddr[i]);
    }
    free(inputLine);
}

我有一个food变量数组,因此在for循环中,我为数组的每个元素调用parseFoodName。第一次调用parseFoodName时,一切正常,但是第二次在*f = createFood(nr)遇到分段错误。任何帮助,我们将不胜感激:)

1 个答案:

答案 0 :(得分:0)

在此行

*foodsAddr = (food*) malloc((*nrOfFoodsAddr+1)* sizeof(food));

您只需设置foodsAddr[0]

您可以通过在malloc之后添加for循环来解决此问题。

for(int i = 1; i < *nrOfFoodsAddr; i++)
    foodsAddr[i] = foodsAddr[i - 1] + 1; // make foodsAddr[i] point to the next element after foodsAddr[i - 1]

或将所有foodsAddr[i]替换为foodsAddr[0] + i