C - 带有结构数组的realloc

时间:2016-11-10 14:31:53

标签: c

我正在做一个结构数组来动态分配产品列表,但这只能工作几次(3~5次),然后我收到了这个错误。

  

*。。/ test':realloc()出错:下一个尺寸无效:0x000055bc0b44f260 *

这是我的代码,这是大学工作的一部分。

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

typedef struct {
    int cod;
    float price;
} Product;

int main () {

    FILE *fp;

    fp = fopen("products.txt", "r+");

    if(fp == NULL)
        fopen("products.txt", "w+");

    int control = 1;
    int choice;
    int tam = 0;
    int i;
    Product *p1;

    p1 = malloc(sizeof(Product));

    while(fread(&p1[0], sizeof(Product), 1, fp) != NULL){
        tam++;
    }

    if(tam > 1){
        rewind(fp);

        p1 = malloc((tam) * sizeof(*p1));

        for (int i = 0; i < tam; i++){
            fread(&p1[i], sizeof(Product), 1, fp);
        }
    }

    rewind(fp);

    do {
        printf("1 - Add product\n2 - Show all products\n3 - Exit\n-> ");
        scanf(" %d", &choice);

        switch (choice) {
            case 1:
                 if (tam == 0) {
                    //p1 = malloc(sizeof(Product));
                    printf("Digit the product code: ");
                    scanf(" %d", &p1[tam].cod);
                    printf("Digit the product price: ");
                    scanf(" %f", &p1[tam].price);
                    tam++;
                } else {
                    printf("***Realloqing: %d***\n", tam * sizeof(*p1));
                    p1 = (Product*)realloc(p1, (tam) * sizeof(Product));
                    for (i = tam; i > 0; i--) {
                        p1[i].cod = p1[i-1].cod;
                        p1[i].price = p1[i-1].price;
                    }
                    printf("Digit the product code: ");
                    scanf(" %d", &p1[0].cod);
                    printf("Digit the product price: ");
                    scanf(" %f", &p1[0].price);
                    tam++;
                }
            break;
            case 2:
                for (i = 0; i < tam; i++) {
                    printf("Product code: %d\nProduct price: %f\n", p1[i].cod, p1[i].price);
                }
            break;
            case 3:
                control = 0;
            break;
        }

    } while (control);

    for (int i = 0; i < tam; i++){
        fwrite(&p1[i], sizeof(Product), 1, fp);
    }

    fclose(fp);

    free(p1);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

此:

p1 = (Product*)realloc(p1, (tam) * sizeof(Product));

违反Realloc的第一个规则,即你不能将realloc的结果直接分配给作为第一个参数传递的同一个变量。当你这样做时,如果它失败了,你就丢失了(泄露了)旧指针。

其次,您不会检查各种功能的返回值,例如malloc()realloc()scanf()。这也是一个罪魁祸首。

如果修复所有这些仍然会使程序损坏,请使用valgrind。

答案 1 :(得分:1)

问题在于:

    printf("***Realloqing: %d***\n", tam * sizeof(*p1));
    p1 = (Product*)realloc(p1, tam * sizeof(Product));

tam为1时,您需要重新分配tam * sizeof(Product),但需要重新分配(tam + 1) * sizeof(Product),因为现在您需要 2 产品的空间。

所以这解决了问题:

    printf("***Realloqing: %d***\n", (tam + 1) * sizeof(*p1));
    p1 = (Product*)realloc(p1, (tam + 1) * sizeof(Product));