-1

Here is a Quick Sort program in C, the program compiles without any errors. But When run and choose random numbers to sort. I get output as follows,

sam@TechTosh ~ $ gcc quick.c
sam@TechTosh ~ $ ./a.out

1> Read from file
2> Random no. Generator


Enter the Choice
2
Starting 10
Segmentation fault

And here is the program, I have debugged a lot of errors from this program, at last its running but cant nor it sort neither it takes input from both types of input that is Read from file or random number generation.

#include<stdio.h>
#include<time.h>
#include<values.h>
#include<malloc.h>
#include<stdlib.h>
#include<unistd.h>
int *a;
void swap(int i,int j)
{
    int temp;
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
}
int partition(int l,int r)
{
    int p,i,j;
    p=a[l];
    i=l;
    j=r+1;
    while(i<j)
    {   
        for(i=i+1;i<r&&a[i]<p;i++)
            for(j=j-1;j>l&&a[i]>p;j++)
                swap(i,j);
    }
    swap(i,j);
    swap(l,j);
    return j;
}
void quick(int l,int r)
{
    int s,i;
    if(l<r)
    {
        s=partition(l,r);
        //delay(1);
        quick(l,s-1);
        quick(s+1,r);
    }
}
void main()
{
    FILE *fp,*fp1;
    clock_t c1,c2;
    int n,i,j,l,r,datasize=1,ch,x,c;
    long int m;
    char file[10];
    do
    {
        printf("\n1> Read from file\n2> Random no. Generator\n\n");
        printf("\nEnter the Choice\n");
        scanf("%d",&ch);
        switch(ch)
        {
            case 1: printf("\nEnter n value\n");
                scanf("%d",&n);
                a=(int*)calloc(n,sizeof(int));
                printf("Enter the filename\n");
                scanf("%s",file);
                fp1=fopen(file,"r");
                i=0;
                while(!feof(fp1))
                {
                    fscanf(fp1,"%d",&a[i]);
                    i++;
                }
                fclose(fp1);
                for(i=0;i<n;i++)
                    printf("%d\t",a[i]);
                quick(0,n-1);
                printf("\nSorted Elements are\n");
                for(i=0;i<n;i++)
                    printf("%d\t",a[i]);
                free(a);
                break;
            case 2: m=100;
                fp=fopen("new.dat","w");
                while(datasize<=10)
                {
                    printf("Starting %ld\n",m);
                    a=(int*)calloc(m,sizeof(int));
                    for(i=0;i<=m-1;i++)
                    {
                        a[i]=rand()%MAXINT;
                        printf("%d",a[i]);
                    }
                    c1=clock();
                    quick(0,m-1);
                    c2=clock();
                    free(a);
                    fprintf(fp,"%ld\t %ld\n",m,(c2-c1)/CLOCKS_PER_SEC);
                    datasize++;
                    m=m+100;
                }
                fclose(fp);
                break;
            default: break;
        }
        printf("To continue, Press 1 else other for Exit!");
        scanf("%d",&c);
    }
    while(c==1);
}
Sammy Sam
  • 3
  • 1
  • 2
    Your question is tantamount to "please debug my code for me". I'd recommend using a debugger to step through the code on a simple non-working example, or using a tool like `valgrind`. – NPE May 24 '14 at 17:55
  • 1
    is this due tomorrow night at midnight PST? ;) – Andbdrew May 24 '14 at 17:56
  • A segmentation fault can usually point you to the location it occurs – Leeor May 24 '14 at 18:02
  • how do you know it is the last bug? – Grady Player May 24 '14 at 18:14
  • The output you show doesn't correspond to the source you show. When you enter `2`, the value of `m` is set to `100`, but you then claim it is printed as `10`. We can't debug the code if you don't show us exactly the code you have problems with! (Also, one of my personal bêtes noires is the use of `` when none of the extra facilities provided by `` are used — use just ``.) – Jonathan Leffler May 24 '14 at 18:21
  • Also, the loop `for(i=0;i<=m-1;i++)` is not idiomatic C. Learn to use: `for (i = 0; i < m; i++)` which is fully equivalent but also idiomatic C (use `<` instead of `<=` most of the time). There are occasions to use `<=`, but this isn't one of them. In the random allocation loop, you don't include a newline or space between the numbers, which leads to odd behaviour. – Jonathan Leffler May 24 '14 at 18:28
  • Initially m was 100, but i changed it to 10 then also same problem., – Sammy Sam May 24 '14 at 18:29
  • OK; but please be careful because it doesn't inspire confidence when there's an obvious discrepancy between the code and the sample output. – Jonathan Leffler May 24 '14 at 18:31
  • After using gdb to debug i got this, Enter the Choice 2 Starting 10 Program received signal SIGSEGV, Segmentation fault. swap ( i=, j=) at quick.c:9 9 { – Sammy Sam May 24 '14 at 18:31
  • See [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). You should also check all input operations, but it probably isn't directly material to your current crash. – Jonathan Leffler May 24 '14 at 18:36
  • its not false always!.. – Sammy Sam May 24 '14 at 18:42
  • I got it fellas!, Just modified the Partition function and its working.. int partition(int low,int high) { int i,j,key,temp; key=a[low]; i=low+1; j=high; while(1) { while(ia[i]) i++; while(a[j]>key) j--; if(i – Sammy Sam May 24 '14 at 18:43
  • Please update the question with the information about the fix. The primary problem was certainly that the partition code was not working correctly. – Jonathan Leffler May 24 '14 at 18:51

1 Answers1

0

Your recursion doesn't end because your partitioning code is not working correctly. Here's an instrumented and marginally cleaned up version of your code (there are still numerous things that should be fixed):

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

#define MAXINT INT_MAX

static int *a;

static void swap(int i, int j)
{
    int temp;
    temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

static int partition(int l, int r)
{
    printf("-->> %s: (%d, %d)\n", __func__, l, r);
    int p, i, j;
    p = a[l];
    i = l;
    j = r + 1;
    while (i < j)
    {
        for (i = i + 1; i < r && a[i] < p; i++)
            for (j = j - 1; j > l && a[i] > p; j++)
                swap(i, j);
    }
    swap(i, j);
    swap(l, j);
    printf("<<-- %s: (%d, %d) => %d\n", __func__, l, r, j);
    return j;
}

static void quick(int l, int r)
{
    int s;
    printf("-->> %s: (%d, %d)\n", __func__, l, r);
    if (l < r)
    {
        s = partition(l, r);
        // delay(1);
        quick(l, s - 1);
        quick(s + 1, r);
    }
    printf("<<-- %s: (%d, %d)\n", __func__, l, r);
}

int main(void)
{
    FILE *fp, *fp1;
    clock_t c1, c2;
    int n, i, datasize = 1, ch, c;
    long int m;
    char file[10];
    do
    {
        printf("\n1> Read from file\n2> Random no. Generator\n\n");
        printf("\nEnter the Choice\n");
        scanf("%d", &ch);
        switch (ch)
        {
        case 1:
            printf("\nEnter n value\n");
            scanf("%d", &n);
            a = (int *)calloc(n, sizeof(int));
            printf("Enter the filename\n");
            scanf("%s", file);
            fp1 = fopen(file, "r");
            i = 0;
            while (!feof(fp1))
            {
                fscanf(fp1, "%d", &a[i]);
                i++;
            }
            fclose(fp1);
            for (i = 0; i < n; i++)
                printf("%d\t", a[i]);
            quick(0, n - 1);
            printf("\nSorted Elements are\n");
            for (i = 0; i < n; i++)
                printf("%d\t", a[i]);
            free(a);
            break;
        case 2:
            m = 10;
            fp = fopen("new.dat", "w");
            while (datasize <= 10)
            {
                enum { PER_LINE = 7 };
                printf("Starting %ld\n", m);
                a = (int *)calloc(m, sizeof(int));
                for (i = 0; i <= m - 1; i++)
                {
                    a[i] = rand() % MAXINT;
                    printf("%11d", a[i]);
                    if (i % PER_LINE == PER_LINE - 1)
                        putchar('\n');
                }
                if (i % PER_LINE != 0)
                    putchar('\n');
                printf("Sorting\n");
                c1 = clock();
                quick(0, m - 1);
                c2 = clock();
                printf("Sorted\n");
                free(a);
                fprintf(fp, "%ld\t %ld\n", m, (c2 - c1) / CLOCKS_PER_SEC);
                datasize++;
                m = m + 10;
            }
            fclose(fp);
            break;
        default:
            break;
        }
        printf("To continue, Press 1 else other for Exit!");
        scanf("%d", &c);
    } while (c == 1);
    return 0;
}

The output starts with:

1> Read from file
2> Random no. Generator

Enter the Choice
Starting 10
      16807  282475249 1622650073  984943658 1144108930  470211272  101027544
 1457850878 1458777923 2007237709
Sorting
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10

…lots more of this…    

-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
-->> partition: (0, 9)
<<-- partition: (0, 9) => 10
-->> quick: (0, 9)
Segmentation fault: 11

Note how I did the debugging — adding appropriate print statements at key places. There's never a line starting <<-- quick:, so the quick sort algorithm never returns.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I got it, and modified the partition function.. int partition(int low,int high) { int i,j,key,temp; key=a[low]; i=low+1; j=high; while(1) { while(ia[i]) i++; while(a[j]>key) j--; if(i – Sammy Sam May 24 '14 at 18:51