miloovann
miloovann

Reputation: 31

quick sort c++ code error segmentation fault 11?

Code:


#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void partition(int *A, int start, int end){ //end is the position of the last number
    cout<<"start is "<<start<<" end is "<<end<<endl;
    if(end - start+1 > 1){
        int i = start + 1, j = start + 1, pivot = A[start];
        while(j <= end){
            if(A[j] <= pivot){
                swap(A[j], A[i]);
                i++;
            }
            j++;
        }
        swap(A[start], A[i-1]);
        partition(A, start, i-1);
        partition(A, i, end);
    }
    
}

void QuickSort(int *A, int n){
    partition(A, 0, n-1);
}


int main() {
    int n, method;
    string sortMethod[ ] = {
            "Insertion sort", "Selection sort", "Bubble sort", "Merge sort", "Quick sort"
    };
    int m = sizeof(sortMethod)/sizeof(string);
    srand(time(0));
    
    while (true){
        cout << "Number of test marks: ";
        cin >> n;
        if ( n==0 ) break;
        int *A = new int[n];
        for (int i=0; i < n; i++) cin>>A[i];
        //A[i] = rand()%101;

        for (int i=0; i < n; i++)cout << A[i] << " ";
        cout<<endl<<endl;


        cout << "Sorting method: \n"; 
        for (int i=0; i < m; i++) cout << i+1 << ": " << sortMethod[i] << endl;
        // cin >> method;
        method = 5;
        cout<<endl;
        int t = time(0);
        
        QuickSort(A,n);

        if (method > m) continue;       
        cout << sortMethod[method-1] << endl;
        if (n <= 100) {
            for (int i=0; i < n; i++) {
                if (i> 0 && i%10==0) cout << endl;
                cout << A[i] << " ";
            }
            cout << endl;
        }
        else {
            cout << "Sorting completed in " <<  time(0) - t  << " sec.\n";
        }
        cout << endl;
    } 
    cout << "Program ends here."<<endl;
    return 0;
}

When some of my input numbers have the same value, I get a "Segmentation fault: 11".

For example, an input of "4 7 7 3 1" would produce infinite lines of the following output: "start is 1 end is 3".

May I ask how should I improve my code? I know that Segfault 11 happens when you try to access an invalid memory, and i think that's likely what I did here, although i cant seem to identify the error. Thanks!

Upvotes: 0

Views: 126

Answers (1)

Noam Weiss
Noam Weiss

Reputation: 211

So this is what's happening here. Imagine that in a certain partition the first element (the pivot) is also the largest.

This means that in every iteration of the while loop the value of A[j]<=pivot will be true and i will be increased.

Since both i and j are increased by 1 in every iteration there value is the same, so at the end of the loop they are both equal to end+1.

Then you are invoking partition(A, start, i-1) which is really the same as partition(A, start, end) - meaning you have an infinite recursion which continues until you reach... well, stack overflow and the program crush with segfault.


The minimal fix will be to make sure that the sub partitions are strictly smaller than the original one by excluding the pivot from them. So something like this:

        partition(A, start, i-2); // i-1 is the pivot, so we don't need to include it
        partition(A, i, end);

Upvotes: 1

Related Questions