Reputation: 31
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
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