GCC Segmentation fault when execute quicksort code - c

I meet an "segmentation falut" while execute my own quick sort source code in C
in gcc version 4.4.3 with ubuntu 13
the code is look like the below
#include<stdio.h>
void Quicksort(int arr[], int start, int end);
void swap(int *a, int *b);
void main(void){
int arr[] = {15,22,13,27,12,10,20,25};
int iLength=sizeof(arr);
Quicksort(arr, 0, iLength-1);
for(int i=0;i<iLength;++i)
printf("%d", arr[i]);
}
void Quicksort(int arr[], int start, int end)
{
int left = start;
int right = end;
if((end-start)>=1)
{
int pivot = arr[start];
while(right>left)
{
while((arr[left]<=pivot)&&(left<=end)&&(right>left))//Limit check array size
left++;
while((arr[right]>pivot)&&(right>=start)&&(right>=left))
right--;
if(right>left)
swap(&arr[left], &arr[right]);
}//end while
swap(&arr[left], &arr[right]);
Quicksort(arr, start, right-1);
Quicksort(arr, right+1, end);
}//end if
else
{
return;
}
}//end Quicksort
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
I don't know what is the problem..
many web search results show that it is a memory issue..
but I don't know what is the exact problem in the above code
please help...

In main
int arr[] = {15,22,13,27,12,10,20,25};
int iLength=sizeof(arr);
This iLength will not contain length of array but its size , that is 8*4(assuming 4 bytes as size of int)= 32.
If you send this in function and use later in loop -
for(int i=0;i<iLength;++i)
printf("%d", arr[i]);
This will access index out of bound (luckily you got segmentation fault).
To calculate length of array you can do this -
int iLength = sizeof arr/sizeof(int);
And then use it .
Note - void main(void) -> int main(void) or int main(int argc,char **argv) .

Related

memory read failed for 0x4e00000000 at the end of the code when array's numbers are randomly generated

So I'm trying to apply (in C) randomly generated numbers to an array which will be sorted with Quick sort. There is no problem with generating numbers and sorting, but at the end of the code I have an error telling me there was a problem with memory reading.
#include <stdlib.h>
#include <time.h>
void generate(int AR[], int n){
srand((unsigned int) time(NULL));
for(int i=0;i<n;i++){
int num = (rand()%100);
AR[i]=num;
}
}// end of generate
void swap(int *a, int *b){
int temp=*a;
*a=*b;
*b=temp;
} //end of swap
int sort(int AR[], int beg, int end){
int pivot= AR[end];
int a=(beg-1);
for(int i=beg; i<=end-1; i++){
if(AR[i]<pivot){
a++;
swap(&AR[i], &AR[a]);
}//end of if
} //end of i<end-1
swap(&AR[a+1], &AR[end]);
return (a+1);
} //end of sort
void Quick_sort(int AR[], int beg, int end){
if(beg<end){
int placed_PV=sort(AR, beg, end);
Quick_sort(AR, beg, placed_PV-1);
Quick_sort(AR, placed_PV+1, end);
} //end of if beg<end
}//end of Quick sort
int main(){
int AR[]={};
int n=10;
generate(AR, n);
printf("\n");
printf("Nieposortowana tablica:");
for(int i=0; i<n;i++)
printf("%d,", AR[i]);
printf("\n");
Quick_sort(AR, 0, n-1);
printf("Posortowana tablica:");
for(int i=0;i<n;i++)
printf("%d,", AR[i]);
printf("\n");
} //end of code
error message is
error: memory read failed for 0x4e00000000
Thread 1: EXC_BAD_ACCESS (code=1, address=0x4e00000000)
Where is the mistake I've made?
you have this:
int AR[]={};
int n=10;
which is wrong because this array AR has only one element(due to this initialization) ,so you can't access ten elements of it.
fix like this
int AR[10]={0};

Calling functions with arrays?

I have some work with this code and i need a swap function that can get a arrays like a[j].
How I need to transport to another function something like this?
#include <stdio.h>
void bubble_sort(int *a, int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n - i - 1; j++) {
if (a[j] > a[j + 1]) swap(&a[j], &a[j + 1]);
}
}
}
This is the code, so how I can call swap function with a[j]? Do I need to call function like this or?
int swap (int a[],int b[])
int swap (int *a,int *b)
With this second call i am sure that it will work Am i right ? But how can i call this function like the first example?
#define MAX 100
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
return 0;
}
void bubble_sort(int a[], int n) {
int i;
for(i=0;i<n;i++)
{
if(a[i]<a[i+1])
swap(a[i],a[i+1]);
}
return 0;
}
int main()
{
int a[4]={1,2,3,0};
int n=4;
bubble_sort(a,n);
for(int i=0;i<n;i++)
{
printf("%d",a[i]);
}
}
I used that code Segmentation fault (core dumped)
Your function needs to take 2 pointers like this:
void swap(int * const a, int * const b) {
int temp = *a;
*a = *b;
*b = temp;
}
int swap (int a[], int b[]); will also work since in function parameters int* a and int a[] are the same thing. But it is confusing - it implies that the pointer is pointing to an array, while you only want to swap 2 integers.
Here's how you could do it the other way:
void swap(int a[], int b[]) {
int temp = *a;
*a = *b;
*b = temp;
}

quicksort implementation trouble

I am encountering the problems in executing the quicksort algorithm.
THere is a error i am encountering but unable to find where the problem is. if someone could point where the error is i will be thankfull.
#include <stdio.h>
#include <stdlib.h>
void main(){
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr,0,n-1);
printArray(arr,0,n-1);
}
//Quicksort Function
void quickSort(int arr[],int low,int high){
if (low < high){
int pi=partition(arr,low,high);
quickSort(arr,low,pi-1);//takes care of lower set of numbers
quickSort(arr,pi+1,high);//takes care of higher elements above pivot
}
}
//Function for partitioing, in my program i am cosidering pivot as the element at high or the last element
int partition(int arr[],int low,int high){
int i,j;
i=(low-1);
int pivot=arr[high];
for(j=low;j<=high;j++){
if(arr[j]<=pivot){
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i+1], &arr[high]);
return (i+1);
}
//function to print array
void printArray(int arr[],int low,int high){
int i;
for(i=low;i<=high;i++){
printf("%d ",arr[i]);
}
}
//function to swap two elements of array
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
The Simple Implementation of QuickSort Algorithm
void q_sort(int v[],int left,int right)
{
int i,last;
if(left>=right)
return;
swap(v,left,(left+right)/2);
last=left;
for(i=left+1;i<=right;i++)
if(v[i]<v[left])
swap(v,++last,i);
swap(v,left,last);
q_sort(v,left,last-1);
q_sort(v,last+1,right);
}
void swap(int v[],int i,int j)
{
int temp;
if(i!=j){
temp=v[i];
v[i]=v[j];
v[j]=temp;
}
}
The problem is in this statement of your partition() -
if(arr[j]<=pivot){
Change it to -
if(arr[j]<pivot){

Using C to implement radix sort

I got stuck in the below question for a few days. I used C to implement radix sort, everything was fine except for one line of code. Could you please help me to solve this issue?
My problem is in the first line of radix_sort function. While I use int semi_sort[12], I can run the program correctly. However, I wanna use the size variable that I passed into the function, but when I use int semi_sort[size] instead of int semi_sort[12], my program would crash. Could anyone tell me why is that? BY the way, I referred to this link, in this author's codes, he did int semiSorted[size]. Why does this line of code work this time?
Thank you in advance!!
#include <stdio.h>
#include <stdlib.h>
#define bucket_size 10
int find_the_largest(int arr[],int size);
void display(int arr[],int size);
void radix_sort(int arr[],int size);
int main()
{
printf("------------------------------------------------------\n");
printf(" Hey! This is a radix sort algorithm!\n");
printf("------------------------------------------------------\n\n");
int array[] = {10, 2, 303, 4021, 293, 1, 0, 429, 480, 92, 2999, 14};
int size = sizeof(array)/sizeof(int);
int largest_num = find_the_largest(array,size);
printf("The unsorted array:");
display(array,size);
printf("The radix sort algorithm:\n\n");
radix_sort(array,size);
display(array,size);
return 0;
}
int find_the_largest(int arr[],int size){
int i,max_num=0;
for(i=0;i<size;i++){
if(arr[i]>max_num)
max_num = arr[i];
}
return max_num;
}
void display(int arr[],int size){
int i;
for(i=0;i<size;i++){
printf(" %d",arr[i]);
if(i==size-1)
printf("\n\n");
}
}
void radix_sort(int arr[],int size){
int semi_sort[12];
int max_num = find_the_largest(arr,size);
int i,significant_num = 1;
while(max_num/significant_num>0){
int bucket[bucket_size] = {0};
for(i=0;i<size;i++){
bucket[(arr[i]/significant_num)%10]++;
}
for(i=1;i<size;i++){
bucket[i] += bucket[i-1];
}
for(i=size-1;i>=0;i--){
semi_sort[--bucket[(arr[i]/significant_num)%10]] = arr[i];
}
for(i=0;i<size;i++)
arr[i] = semi_sort[i];
significant_num *= 10;
}
}
You have problem with code:
for(i=1;i<size;i++){
bucket[i] += bucket[i-1];
}
Because size can be greater then bucket_size.
And probably you have problem with:
for(i=size-1;i>=0;i--){
semi_sort[--bucket[(arr[i]/significant_num)%10]] = arr[i];
}
Because --bucket[(arr[i]/significant_num)%10] can be greater then 11 or less then 0.
And find_the_largest does not work correct on negative numbers.
You can dynamically allocate memory for your buffers, like this:
semi_sort = malloc(size * (sizeof *semi_sort));
And don't forget to free memory on end (free(semi_sort)).

Mergesort, using a for loop to do merge

I am trying to write the code in C for mergesort using for loop in the merge function. Unfortunately it is not working. In the main function I create an array on 10 ints in descending order and then I call the mergesort function to sort them. There is obviously an error in the merge function, since the ascending order is never realized and in some array sizes some long numbers intrude. What am I doing wrong? Here's the function:
#include <stdio.h>
#include <stdlib.h>
void mergesort(int array[], int left, int right);
int main()
{
int i;
int arr[10];
for(i=10;i>0;i--){
arr[10-i]=i;
}
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
mergesort(arr,0,9);
puts("\n");
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
return 0;
}
void mergesort(int array[], int left, int right)
{
void merge(int array[],int left, int mid, int right);
int mid;
if(left<right){
mid=(left+right)/2;
mergesort(array,left,mid);
mergesort(array,mid+1,right);
merge(array,left,mid,right);
}
}
void merge(int array[], int left, int mid, int right)
{
int i;
int l=0;
int r=mid+1;
int arr_sorted[10];
for(i=0;i<=right;i++){
if((l<=mid) && (r<=right)){
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
}
else {
arr_sorted[i]=array[r];
r++;
}
}
if(l>mid){
arr_sorted[i]=array[r];
r++;
}
if(r>right){
arr_sorted[i]=array[l];
l++;
}
}
for(i=0;i<=right;i++){
array[i]=arr_sorted[i];
}
}
First that is looking strange is why you are passing left parameter to the merge, but iterate from 0 to right; left is not even using in this function.
Some corrections that were needed in the merge function :
void merge(int array[], int left, int mid, int right)
{
int i;
int l=left; //If you are passing left, then it should be used here !!
int r=mid+1;
int arr_sorted[10];
for(i=0;(l<=mid)&&(r<=right);i++){
//Your condition for this loop unnecessarily complicates the rest of the code. This is a better way to go about it
//The loop body is fine
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
}
else {
arr_sorted[i]=array[r];
r++;
}
}
//Now, checking for remaining elements and adding them to the result
//The conditions are simple because of the test condition we used in the previous for loop
if(l>mid){
for(;r<=right;r++,i++) arr_sorted[i]=array[r];
}
if(r>right){
for(;l<=mid;l++,i++) arr_sorted[i]=array[l];
}
}
for(i=0;i<=right;i++){
array[i]=arr_sorted[i];
}
}
Also, as a matter of style, try to keep your forward declarations in one place (more so as the functions are related). Instead of :
void mergesort(int array[], int left, int right)
{
void merge(int array[],int left, int mid, int right);//This line should be moved to the top with the mergesort forward declaration
int mid;
if(left<right){
mid=(left+right)/2;
Try doing :
#include <stdio.h>
#include <stdlib.h>
void mergesort(int array[], int left, int right);
void merge(int array[],int left, int mid, int right); // <--------
This is just a matter of preference, though.
here is the entire working merge sort, you can see the differences, let me know if you have any further questions. I had to change the name because stdlib has mergesort implementation.
#include <stdio.h>
#include <stdlib.h>
int mymergesort(int array[], int left, int right);
int main()
{
int i;
int arr[10];
for(i=10;i>0;i--){
arr[10-i]=i;
}
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
mymergesort(arr,0,9);
puts("\n");
for(i=0;i<10;i++){
printf("arr[%d] = %d\n",i,arr[i]);
}
return 0;
}
int mymergesort(int array[], int left, int right)
{
void mymerge(int array[],int left, int mid, int right);
int mid;
mid=(left+right)/2;
if(left<right){
mymergesort(array,left,mid);
mymergesort(array,mid+1,right);
mymerge(array,left,mid,right);
}
return 0;
}
void mymerge(int array[], int left, int mid, int right)
{
int i=0;
int l=left;
int r=mid+1;
int arr_sorted[10];
for(i=left;i<=right;){
if((l<=mid) && (r<=right)){
if(array[l]<array[r]){
arr_sorted[i]=array[l];
l++;
i++;
}
else {
arr_sorted[i]=array[r];
r++;
i++;
}
}
if(l>mid){
for(;r<=right;r++){
arr_sorted[i]=array[r];
i++;
}
break;
}
if(r>right){
for(;l<=mid;l++){
arr_sorted[i]=array[l];
i++;
}
break;
}
}
for(i=left;i<=right;i++){
array[i]=arr_sorted[i];
}
}

Resources