Постоянно получаю сообщение об ошибке: free (): при чтении файла в tcache2 обнаружено двойное освобождение - PullRequest
0 голосов
/ 04 апреля 2020

Я делаю программу на C, которая будет читать документ с номером (предположительно длинным) и помещать их в динамический массив c, а затем сортировать массив. Я продолжаю получать сообщение об ошибке free (): обнаружение двойного освобождения в tcache2 , и я не уверен, происходит ли это из-за функции pu sh или из-за способа, которым я реализовал получение каждой строки в документе. Любая помощь приветствуется.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void push(long *arr,long value, int *size){
    //printf("%ld",value);
    arr = realloc(arr,8 + (8 * (*size + 1))); //allocate 4 more bytes to the arr
    arr[*size] = value; //add the value to the end of array
    *size = *size + 1; //increase size of array
}
int cmpfunc (const void * a, const void * b) {
       return ( *(long*)a - *(long*)b );
}
int main(int argc,char** argv){
    if(argc != 2){
        fprintf(stderr,"Error too many arguments");
        exit(1);
    }
    FILE *fp = fopen(argv[1],"r+");
    if(fp == NULL){
        fprintf(stderr,"Error file not found, Error Number: %d\n",errno);
        exit(1);
    }

    int size = 0;

    long* arr = (long*) malloc(8);  //allocate some mememory to be able to store data points from the file
    char str[256]; //create a string capable of storing each singluar line, 10 because the max amount of                
    while(fgets(str,sizeof(str),fp)){
        printf("%s",str);
        push(arr,atol(str),&size);
    }
    qsort(arr,size,8,cmpfunc);
    fclose(fp);
    return 0;
}

1 Ответ

1 голос
/ 04 апреля 2020

Эта функция

void push(long *arr,long value, int *size){
    //printf("%ld",value);
    arr = realloc(arr,8 + (8 * (*size + 1))); //allocate 4 more bytes to the arr
    arr[*size] = value; //add the value to the end of array
    *size = *size + 1; //increase size of array
}

не изменяет исходный указатель обр. Он имеет дело с копией указателя. Таким образом, вызов reallo c в функции каждый раз пытается освободить один и тот же объем уже освобожденной памяти.

Вы должны передать указатель по ссылке

void push(long **arr,long value, int *size){
    //printf("%ld",value);
    *arr = realloc(*arr,8 + (8 * (*size + 1))); //allocate 4 more bytes to the arr
    ( *arr )[*size] = value; //add the value to the end of array
    *size = *size + 1; //increase size of array
}

и вызвать его вроде

push( &arr,atol(str),&size);

Обратите внимание на то, что такой вызов функции reallo c

    *arr = realloc(*arr,8 + (8 * (*size + 1))); //allocate 4 more bytes to 

небезопасен. Функция может возвращать NULL. В этом случае адрес ранее выделенной памяти будет потерян.

Вам следует использовать некоторую промежуточную переменную. Если распределение прошло успешно, присвойте указателю *arr значение промежуточного значения.

...