realloc () проблемы со старым размером - PullRequest
0 голосов
/ 20 ноября 2018

Я хочу прочитать много информации из файла, поэтому мне нужна динамическая память.Вот почему я использую malloc для своей структуры в основном.Я хотел перераспределять каждую новую строку, полученную из файла, но он говорит «realloc (): недопустимый старый размер» и даже не перераспределяет один раз.

typedef struct{
 int anzahl;
 int ANR;
 char MHD[10];
 char Bezeichnung[20];
 char VPE[5];
 float Preis;
 float gesamtpreis;
}Ware; 

int DateiLesen(Ware *Rechnung)
{
FILE *datei_lesen = NULL;
char trennung[] = " :,;\n\0=";
char zeilen_lesen[256] = {0};
char *formatierer = NULL;
int count = 0;

datei_lesen = fopen("artikel.txt","r");
while(fgets(zeilen_lesen,256,datei_lesen))
{
    count++;
}
fclose(datei_lesen);
if(count == 0)
{
    return -1;
}
datei_lesen = fopen("artikel.txt","r");
while(fgets(zeilen_lesen,256,datei_lesen))
{
    fputs(zeilen_lesen,datei_lesen);
    formatierer = strtok(zeilen_lesen,trennung);
    if(atoi(formatierer) >= 100000)
    {
        Rechnung->ANR = atoi(formatierer);
        formatierer = strtok(NULL,trennung);
        strcpy(Rechnung->MHD,formatierer);
        formatierer = strtok(NULL,trennung);
        strcpy(Rechnung->Bezeichnung,formatierer);
        formatierer = strtok(NULL,trennung);
        strcpy(Rechnung->VPE,formatierer);
        formatierer = strtok(NULL,trennung);
        Rechnung->Preis = atoi(formatierer);
        Rechnung =  realloc(Rechnung,1*sizeof(Ware));
        //Rechnung = (Ware*) realloc(Rechnung,1);
        Rechnung++;
    }
}
fclose(datei_lesen);
return 0;
}


int main(void) {
Ware *Rechnung = (Ware*) malloc(sizeof(Ware));
int test = 0;

initialisiere(&Rechnung);
test = DateiLesen(&Rechnung);
return EXIT_SUCCESS;
}

1 Ответ

0 голосов
/ 20 ноября 2018

Это не то, как вы увеличиваете массив.

Сначала

Rechnung++;

в порядке, но Rechnung больше не является указателем, возвращаемым предыдущим вызовом malloc или realloc. Так что вы не можете ни realloc, ни free это.

Во-вторых,

Rechnung =  realloc(Rechnung,1*sizeof(Ware));

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

Типичный цикл роста массива часто выглядит так:

Data *array = NULL; // note it's fine to realloc a NULL
size_t size = 0;
while (fgets(...)) {
    size_t new_size = size + 1;
    Data *new_array = realloc(array, sizeof(Data) * new_size);
    if (new_array == NULL) {
       // report an error, exit, abort, try again, whatever
       // note having a separate `new_array` variable allows you 
       // to retain old data in `array` in the case of `realloc` erroring on you
    } else {
       array = new_array;
       array[size].foo = make_foo();
       array[size].bar = make_bar();
       size = new_size;
    }
}

Обратите внимание, что вы никогда не увеличиваете array, потому что вы не можете передать увеличенное значение array в realloc. Вы также не можете иметь что-то вроде этого:

    Data *array = malloc(sizeof(Data));
    Data *current = data;
    while (...) {
        ...
        current->foo = make_foo();
        current->bar = make_bar();
        array = realloc(array, sizeof(Data) * new_size);
        current++;
    }

, поскольку realloc может и будет возвращать указатель, отличный от того, который был передан, и current станет недействительным. Поэтому используйте обычную индексацию скучных массивов.

...