0

I am making a program in C that would read a document with a number (supposedly long) and would put them in a dynamic array and then sort the array. I keep on getting the error free(): double free detected in tcache2 and am unsure if it is because of the push function or because of the way I implemented getting each line in the document. Any help is appreciated.

#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;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Please don't use [*magic numbers*](https://en.wikipedia.org/wiki/Magic_number_(programming)). In your allocations what does the numbers `8` stand for? – Some programmer dude Apr 03 '20 at 21:51
  • 4
    `arr = realloc()`. That changes a **local** variable. Caller's variable is not changed. Either return the pointer and have the caller assign back to original variable or pass in a double pointer to the function. – kaylum Apr 03 '20 at 21:53
  • Does this answer your question? [Changing address contained by pointer using function](https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function) – kaylum Apr 03 '20 at 21:55
  • `"Error file not found, Error number:%d\n"` is far less useful (and probably more confusing) than a simple `"Error: %s %s", argv[1], strerror(errno)`, and it would suffice to write `perror(argv[1])`. – William Pursell Apr 03 '20 at 21:59

1 Answers1

1

This function

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
}

does not change the original pointer arr. It deals with a copy of the pointer. So the call of realloc in the function each time tries to free the same extent of already freed memory.

You have to pass the pointer by reference

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
}

and call it like

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

Pay attention to that such a call of the function realloc

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

is unsafe. The function can return NULL. In this case the address of the early allocated memory will be lost.

You should use some intermediate variable. If the allocation was successful assign to the pointer *arr the value of the intermediate varaible.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335