I have this heapsort program which run on Windows, but is giving segmentation fault on ubuntu 14.04.
#include<stdio.h>
#define N 5000
int arr[N];
int size=N-1;
int parent(int i)
{
return (i-1)/2;
}
int lchild(int i)
{
return 2*i+1;
}
int rchild(int i)
{
return 2*i+2;
}
void maxheapify(int arr[],int i)
{
int larg,t;
int l=lchild(i);
int r=rchild(i);
if(arr[l]>arr[i] && l<=size)
larg=l;
else
larg=i;
if(arr[r]>arr[larg] && r<=size)
larg=r;
if(larg!=i)
{
t=arr[larg];
arr[larg]=arr[i];
arr[i]=t;
maxheapify(arr,larg);
}
}
void buildmaxh(int arr[])
{
int i;
for(i=N/2-1;i>=0;i--)
maxheapify(arr,i);
}
void heapsort(int arr[])
{
int i,t;
buildmaxh(arr);
size--;
for(i=N-1;i>0;i--,size--)
{
t=arr[0];
arr[0]=arr[i];
arr[i]=t;
maxheapify(arr,0);
}
}
int main()
{
srand(time(NULL));
int i;
for( i=0;i<N;i++)
arr[i]=rand()%101;
heapsort(arr);
printf("done\n\n");
return 0;
}
What is the source of error? How can I remove this error?
I tried debugging the code using gdb as explained here. But I can't compile the program as described in the answer. I used command gcc myfile.c -ggdb myfile.
Also,using command: gcc myfile.c -o myfile I compiled the program successfully, which gave me segmentation error.
What am I doing wrong?
Thanks.
The error occurs in maxheapify when you check which of the children is larg:
if (arr[l]>arr[i] && l<=size) ...
You've got the checks the wrong way round. When you read arr[l], l might be out of bounds, which is a segmentation violation. If you check the bounds first like this:
if (l<=size && arr[l]>arr[i]) ...
the read access won't happen if l is out of bounds. (Remember that the && and || operators short-circuit the evaluation: In a && b, b is never checked if a is already false, because there's no way the whole expression can be true.)
The same goes for the check of arr[r] some lines after that.
Also, please include <stdlib.h> and <time.h>; they are needed for your randomisation code.
Related
can someone help me to find what cause segmentation fault in my program, I used the gdb but I cannot find which line that cause the error.
Array* Merge(Array *arr1, Array *arr2)
{
int i,j,k;
i=j=k=0;
Array *arr3 = (Array*)malloc(sizeof(Array));
arr3->size = arr1->size + arr2->size;
arr3->length = arr1->length + arr2->length;
while(i<arr1->length && j<arr2->length)
{
if(arr1->A[i] < arr2->A[j])
arr3->A[k++]=arr1->A[i++];
else
arr3->A[k++]=arr2->A[j++];
}
for(;i<arr1->length;i++)
arr3->A[k++]=arr1->A[i];
for(;j<arr2->length;j++)
arr3->A[k++]=arr2->A[j];
return arr3;
}
#include <stdio.h>
#include <stdlib.h>
#include "array1.h"
int main()
{
Array arr,arr1,*arr2;
arr.size=10;
arr.length=5;
arr1.size=10;
arr1.length=5;
arr.A=(int*)malloc(arr.size*sizeof(int));
arr1.A=(int*)malloc(arr.size*sizeof(int));
printf("\n enter elements of arr\n");
for (int i=0;i<arr.length;i++)
scanf("%d",&arr.A[i]);
/**********************************************/
printf("\n enter elements of arr1\n");
for (int i=0;i<arr1.length;i++)
scanf("%d",&arr1.A[i]);
arr2=Merge(&arr, &arr1);
display(*arr2);
return 0;
}
here is the result of the gdb
enter image description here
In Merge you don't allocate any space for arr3's data (probably a member called A looking at the other code)
It would help to see the rest of the code (especially the declaration of Array) but I suspect arr3->A is an uninitialised pointer.
I wrote a small program that fills an array with prime numbers which are returned from a separate function. The program compile fine but when i go to run the executable i get the above error. Here is my source code. I'm not really sure why its happening. Could anyone here do me the huge favor of compiling and running the following code? I'm wondering if its something on my laptop but i really have no clue. I'm running linux mint if that helps at all.
#include <stdio.h>
int prime(int x);
int main()
{
int intergers,index,return_value;
int array[100]={2}; /*intialize array[0] being 2*/
for(index=1;index<100;index=index+1) /*begin array index at array[1]*/
{
for(intergers=3;intergers<102;intergers=intergers+1) /*check for prime numbers starting from 3*/
{
return_value = prime(intergers);
if(return_value==999)
array[index]=-1;
else
array[index]=return_value;
}
}
printf("hello world");
}
int prime(int x)
{
int divisors,count,value;
for(divisors=2;divisors<x;divisors=divisors+1)
{
if(x%divisors==0)
{
value=999;
break;
}
else
{
value=x;
}
}
return value;
}
The following code compiled and linked without errors or warnings from the gcc compiler on SuSE SLES 11 using the following command: gcc -Wall -o test test.c
#include <stdio.h>
int prime(int x);
int main()
{
int intergers,index,return_value;
int array[100]={2}; /*intialize array[0] being 2*/
for(index=1;index<100;index=index+1) /*begin array index at array[1]*/
{
for(intergers=3;intergers<102;intergers=intergers+1) /*check for prime numbers starting from 3*/
{
return_value = prime(intergers);
if(return_value==999)
array[index]=-1;
else
array[index]=return_value;
}
}
printf("hello world\n");
return(0); // Added this line to rid compiler: warning: control reaches end of non-void function
}
int prime(int x)
{
int divisors,/* count, */ value;
for(divisors=2;divisors<x;divisors=divisors+1)
{
if(x%divisors==0)
{
value=999;
break;
}
else
{
value=x;
}
}
return value;
}
I then executed the program:
> ./test
hello world
The code executed as expected.
I was writing a C code for quick sort but something went wrong. After some debugging i finally found where my code was going wrong.
When i replaced
{
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
with
{
tmp=a[lp];
a[lp]=a[ub];
a[ub]=tmp;
}
my code started working.
I am Curious to know why my initial implementation of swapping didn't work?
Can anyone help me?
#include<stdio.h>
#define swap(a,b) (a)=(a)+(b);b=(a)-(b);(a)=(a)-(b);
int a[]={7,1,5,2,3};
int partition(int lb,int ub)
{
int k,hp,lp;
k=a[ub];
lp=lb-1;
for(hp=lb;hp<ub;hp++)
{
if(a[hp]<k)
{
lp++;
int tmp=a[lp];
a[lp]=a[hp];
a[hp]=tmp;
}
}
lp++;
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
return lp;
}
void quicksort(int lb,int ub)
{
if(lb<ub)
{
int pos=partition(lb,ub);
quicksort(lb,pos-1);
quicksort(pos+1,ub);
}
}
int main()
{
quicksort(0,4);
int i;
for(i=0;i<5;i++)printf("%d ",a[i]);
printf("\n");
return 0;
}
You need to consider what happens when lp == ub (ie. you are being asked to swap an element with itself).
Change it to this:
if (lp != ub) {
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
Example: http://ideone.com/AS1Dgf
i am tring to solve this http://www.spoj.com/problems/LEXISORT/ question
it working fine in visual studio compiler and IDEone also but when i running in SPOJ compiler it is getting SEGSIGV error
Here my code goes
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *getString();
void lexisort(char **str,int num);
void countsort(char **str,int i,int num);
int main()
{
int num_test;
int num_strings;
char **str;
int i,j;
scanf("%d",&num_test);
for(i=0;i<num_test;i++)
{
scanf("%d",&num_strings);
str=(char **)malloc(sizeof(char *)*num_strings);
for(j=0;j<num_strings;j++)
{
str[j]=(char *)malloc(sizeof(char)*11);
scanf("%s",str[j]);
}
lexisort(str,num_strings);
for(j=0;j<num_strings;j++)
{
printf("%s\n",str[j]);
free(str[j]);
}
free(str);
}
return 0;
}
void lexisort(char **str,int num)
{
int i;
for(i=9;i>=0;i--)
{
countsort(str,i,num);
}
}
void countsort(char **str,int i,int num)
{
int buff[52]={0,0},k,x;
char **temp=(char **)malloc(sizeof(char *)*num);
for(k=0;k<52;k++)
{
buff[k]=0;
}
for(k=0;k<num;k++)
{
if(str[k][i]>='A' && str[k][i]<='Z')
{
buff[(str[k][i]-'A')]++;
}
else
{
buff[26+(str[k][i]-'a')]++;
}
}
for(k=1;k<52;k++)
{
buff[k]=buff[k]+buff[k-1];
}
for(k=num-1;k>=0;k--)
{
if(str[k][i]>='A' && str[k][i]<='Z')
{
x=buff[(str[k][i]-'A')];
temp[x-1]=str[k];
buff[(str[k][i]-'A')]--;
}
else
{
x=buff[26+(str[k][i]-'a')];
temp[x-1]=str[k];
buff[26+(str[k][i]-'a')]--;
}
}
for(k=0;k<num;k++)
{
str[k]=temp[k];
}
free(temp);
}
Generally speaking, these online judge programs give an example input (in this case, that input appears to work perfectly), but also use a set of harder hidden inputs.
In this case, what happens if the input string has a space in it? For example, an input of:
1
2
hello orld
whateverss
In this case, your scanf("%s",str[j]); will not properly read that input line. I'd suggest switching over to a getline style interface, rather than a scanf style interface.
Ok this has been driving me crazy. I solved a problem on spoj called MIXTURES (http://www.spoj.com/problems/MIXTURES/). I don't know why i keep getting segmentation fault. There is also one catch in the problem that there is no explicit indicator for end of input. I think I have handled it correctly but correct me if I am wrong. Here is my code
#include<stdio.h>
#include<stdlib.h>
typedef struct temp
{
int modSum; //the modular sum of the cluster
int smoke; //the minimum smoke that a cluster can give.
}clusterInfo;
int fxDP(int *A,int len)
{
int i,j,k,smoke1,smoke2;
clusterInfo **dpArr=(clusterInfo **)malloc(sizeof(clusterInfo *)*(len-1));
for(i=0;i<len-1;i++)
dpArr[i]=(clusterInfo *)malloc(sizeof(clusterInfo)*(len-i-1)); //len- ( (i+2) -1)= len-i-1
//dpArr[i] gives info of all clusters of length i+2
//base case for clusterLength=2
for(i=0;i<len-1;i++)
{
dpArr[0][i].modSum=(A[i]+A[i+1])%100;
dpArr[0][i].smoke=A[i]*A[i+1];
}
//endBase Case
//induction
for(i=1;i<len-1;i++) //lengthOfCluster=i+2
{
for(j=0;j<len-i-1;j++) //len-i-1+i+2-1=len
{
smoke1=(dpArr[i-1][j].modSum*A[j+(i+2)-1]) + dpArr[i-1][j].smoke;
smoke2=(A[j]*dpArr[i-1][j+1].modSum) + dpArr[i-1][j+1].smoke;
dpArr[i][j].smoke=smoke1<smoke2 ? smoke1:smoke2 ;
dpArr[i][j].modSum=(dpArr[i-1][j].modSum+A[j+(i+2)-1])%100;
}
}
int result=dpArr[len-2][0].smoke;
free(dpArr);
return result;
}
int main()
{
int *A; int len,i;
while(1)
{
scanf("%d",&len);
if(feof(stdin)) break;
A=(int *)malloc(sizeof(int)*len);
for(i=0;i<len;i++)
scanf("%d",&A[i]);
printf("%d\n",fxDP(A,len));
}
return 0;
}
int result=dpArr[len-2][0].smoke;
What happens if len=1 ??