1

I'm writing a program that reads an array of employee records from an input file and sorts them separately using insertion sort and quick sort. It also finds out the time taken by the two sorts for different array sizes. I'm supposed to find the estimated cutoff size above which quick sort becomes faster than insertion sort. For doing that I have written the function estimateCutoff() which in turn calls testRun()...(testRun() finds the time taken for sorting a particular array while estimateCutoff() compares the two times). However I'm getting a particular error each time the program runs which is :

realloc(): invalid next size
Aborted (core dumped)

Upon debugging the code I have found out that the error occurs during allocation of array emp2 in testRun() that has been in return called by estimateCutoff().

realloc(): invalid next size
Program received signal SIGABRT, Aborted. __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.

Can anybody please tell me where I'm going wrong.

int estimateCutoff(empl * emp,int size){
    int min=0,max=size,mid;
    mid=(min+max)/2;
    time t=testRun(emp,mid);

    do
    {
        if(t.IStime<t.QStime)
            min=mid;
        else if(t.IStime>t.QStime)
            max=mid;
        else if(t.IStime==t.QStime)
            return mid;
        mid=(min+max)/2;
        t=testRun(emp,mid);
    } while(mid!=min && mid!= max);

    return mid;
}

This is the testRun() function:

time testRun(empl * emp,int size){
    int i;
    empl *emp1=malloc(sizeof(empl)*size);
    for(i=0;i<size;i++)
    {
        emp1[i]=emp[i];
    }

    time t;
    struct timeval t1,t2,t3,t4;
    double elapsedTime1,elapsedTime2;

    gettimeofday(&t1,NULL);
    iter_insertionsort(emp1,size);
    gettimeofday(&t2,NULL);
    elapsedTime1=(t2.tv_sec-t1.tv_sec)*1000.0;
    elapsedTime1+=(t2.tv_usec-t1.tv_usec)/1000.0;
    t.IStime=elapsedTime1;

    empl *emp2=malloc(sizeof(empl)*size);
    for(i=0;i<size;i++)
    {
        emp2[i]=emp[i];
    }

    gettimeofday(&t3,NULL);
    itr_quicksort(emp2,size,1);
    gettimeofday(&t4,NULL);
    elapsedTime2=(t4.tv_sec-t3.tv_sec)*1000.0;
    elapsedTime2+=(t4.tv_usec-t3.tv_usec)/1000.0;
    t.QStime=elapsedTime2;

    return t;
}

The main() function is given below:

#include<stack.h>
#include<quick.h>
int main(){

    int arraycapacity=10;
    empl * emp=malloc(sizeof(empl)*arraycapacity);
    FILE * ptr=fopen("1000","r");
    int size=0;
    while(!feof(ptr))
    {
        fscanf(ptr,"%[^ ] %d\n",emp[size].name,&(emp[size].empID));
        size++;
        if(size==arraycapacity)
        {
            arraycapacity=arraycapacity*2;
            emp=realloc(emp,sizeof(empl)*arraycapacity);
        }
    }
    int mid=estimateCutoff(emp,size);
    printf("mid = %d\n",mid);
    fclose(ptr);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
VITTHAL BHANDARI
  • 139
  • 2
  • 5
  • 15
  • The message means you've gone trampling outside the bounds of a piece of allocated memory and have corrupted the control information that the memory management code uses. If possible, get [Valgrind](http://valgrind.org/) and use it to diagnose the problem. Failing that, work out where you're trampling out of bounds. – Jonathan Leffler Mar 03 '19 at 08:30
  • 2
    Note that [`while (!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). – Jonathan Leffler Mar 03 '19 at 08:33
  • I'll use Valgrind then and see if that works. – VITTHAL BHANDARI Mar 03 '19 at 08:34
  • and thanks for the info BTW !! – VITTHAL BHANDARI Mar 03 '19 at 08:38
  • @JonathanLeffler valgrind gives the following errror: VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting --10016-- si_code=1; Faulting address: 0x790523C492; sp: 0x1002ca9e30 valgrind: the 'impossible' happened: Killed by fatal signal – VITTHAL BHANDARI Mar 03 '19 at 09:00

1 Answers1

3

In main you are doubling the array size for every test but never check if realloc was successful.

You are calling malloc twice in every call to testRun which is happening from inside a loop in estimateCutoff, but you never free any memory and you never check if malloc was successful.

This is all a recipe for disaster. You should take the following steps:

  • Check that all memory allocation and reallocation succeeds.
  • free() the memory allocations at the end of each test in testrun.
  • Set a limit on arraycapacity
  • Change the control loop in main which wrongly uses feof() to


while(fscanf(ptr, "%[^ ] %d\n", emp[size].name, &(emp[size].empID)) == 2)
{
    // ...
}

because the scanf family returns the number of items successfully scanned.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • I did as you said, however, after a few iterations ,program still gives error : Continuing. corrupted size vs. prev_size Program received signal SIGABRT, Aborted. __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. – VITTHAL BHANDARI Mar 03 '19 at 12:10
  • Perhpas there is a fault in the sorting functions. – Weather Vane Mar 03 '19 at 12:11
  • The sorting function are working just fine and so is testRun() independently. It's only when I use estimateCutoff() that the error happens. – VITTHAL BHANDARI Mar 03 '19 at 12:56
  • Suppose `else if(t.IStime==t.QStime)` is never true? They are floating point values. Anyway you have already tested `<` and `>` so why the `else` and a needless test? – Weather Vane Mar 03 '19 at 13:11