Why am I getting segmentation fault in my following C code? - c

This is a problem from spoj named prime1. The code seems to be correct to me. This even runs and produces desirable results on ideone.com but spoj gives me a runtime error, saying this is a segmentation fault. I can't find any memory leaks, no buffer overflow, etc. Please help me find the segmentation fault.
#include <stdio.h>
unsigned int arr[32200];
int prime()
{
unsigned int i,j,k=2;
int flag;
arr[0]=2;
arr[1]=3;
for (i=5;i<32200;i+=2)
{
flag=0;
for(j=3;j<i;j+=2)
{
if(i%j==0)
{
flag=1;
break;
}
}
if (flag==0)
{
arr[k++]=i;
}
}
return 0;
}
int main()
{
int t;
unsigned int a,b,i,m;
scanf("%d",&t);
prime();
while(t--)
{
scanf("%u%u",&a,&b);
for(i=0;;i++)
{
if (arr[i]>=a)
{
m=i;
break;
}
}
while(arr[m]<=b)
{
printf("%u\n",arr[m]);
m++;
}
printf("\n");
}
return 0;
}

If an a is given that is greater than all elements in arr, the first for() loop in main() overruns the array, yielding undefined behavior. The fact that the global variable arr will be zero initialized helps to trigger this condition: start with any a other than zero, and you immediately have undefined behavior.

The array you are keeping your primes is too small.
The maximum number you can have as b is 10^9 and the smallest for a is 1. Therefore, you need to store all primes between 1 and one billion.
If you type "how many primes between 1 and 1000000000" in wolfram alpha, for instance, you will get that there are 50847534 primes between those two. So your array is too small.
Also, after you fix that, you're getting a TLE. Your code is too inefficient for this problem. You need to develop a faster method to generate the prime numbers.

Related

Floating point exception (core dumped) - Non-square numbers finder

i have a problem. I've been making this for hours, and i finally thought i had a draft, i solved a few mistakes i made, but now it's typing out "Floating point exception (core dumped)" when i run it. I was able to solve a few other issues, but I don't think i can get over this one without basically starting from scratch, i have no idea what could be causing this, i wonder if any more knowledgeable people here could take a look and try to spot a possible mistake. My program is supposed to find Non-square numbers - numbers not divisible by squares of whole numbers. It first finds squares to divide by, and then divides Non-square number candidates up to a specified integer. Then it types out all the numbers it finds. I think it's quite possible i've made a mistake in pointer usage, i have not yet quite mastered those, and most likely couldn't solve a related issue anyway.
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
int isNonSq (int a,int sqr) {
int b=0.75*a;
for (int i=2;i<b;i++) {
if (a%sqr[i]==0) return 0;
}
return 1;
}
int main ( void ) {
int a;
int * resNum;
int * sqr;
while (!feof(stdin)) {
if (scanf(" %d",&a)!=1||a<=0) {
printf("Nespravny vstup.\n");
return 0;
} else {
int b, c=1;
b=0.75*a;
resNum=(int)malloc(a*sizeof(resNum));
sqr=(int)malloc(a*sizeof(*sqr));
for (int i=2;i<sqrt(a);i++)
sqr[i]=pow(i,2);
for (int i=1;i<b;i++) {
if (isNonSq(i,sqr)) {
resNum[c]=i;
c++;
}
}
}
}
for (int i=1;i<a;i++) {
printf(" %d",resNum[i]);
}
printf("\n");
free(resNum);
free(sqr);
return 0;
}
This could be occurring because of an NaN or an infinite number, I would recommend you use gdb to figure out what is happening when you run your compiled c code. https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_gdb.php
Goodluck!

Segmentation fault (core dumped) in a simple C code due to large range of values the variable takes

I have written the following code to find the largest palindrome formed by the product of 3-digit numbers. There is a problem with the nested loops which is giving the segmentation fault. Can someone help me with the debugging?
The code works fine for smaller numbers but gives segmentation fault for larger numbers (which is the reason I took long int instead of int for k, l, max and a variables).
#include<stdio.h>
long reverse(long);
main()
{
long k, l, max, a[100];
int i, j, t=0;
printf("hello\n");
for(i=999; i>99; i--)
{
for(j=999; j>99;j--)
{
// printf("hello\n");
k=i*j;
l= reverse(k);
if(k==l) {a[t]=k; t++; }
}
}
printf("hello\n");
max=a[0];
for(t=1;t<100; t++)
{
if(max<a[t]) {max=a[t];}
}
printf("Largest palindrome is %ld\n", max);
}
long reverse(long n)
{
long rev=0;
while(n!=0)
{
rev= rev*10;
rev= rev+n%10;
n=n/10;
}
return rev;
}
For large numbers, t increases beyond the size of the array a.
This will cause the program to write on the program stack where it shouldn't which can cause a crash with a core dump.
If you only want to find the largest palindrome, you don't to save them all. You can just save the largest one.
Since your a is only 100 elements long, you need to ensure t is always less than 100 or you will overflow the bounds of your array. You might want to use realloc to dynamically allocate a using a pointer.

C program to find the n'th prime number-

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int prime(long long int);
long long int *arr; //array to hold n prime numbers
int main()
{
int i,count=4;;
long long int n;
scanf("%lli",&n);
arr=malloc(sizeof(long long int)*n);
arr[0]=2;
arr[1]=3;
arr[2]=5;
arr[3]=7;
if (n==1) printf("%lli",arr[0]);
else{ if (n==2) printf("%lli",arr[1]);
else{ if (n==3) printf("%lli",arr[2]);
else{ if (n==4) printf("%lli",arr[3]);
else
{
for(i=2;count<n;i++)
{
if(prime(6*i-1)) { /*As prime nos are always 6k+1 or
arr[count]=6*i-1; 6k-1fork>=2 I checked only for those*/
count++; }
if(prime(6*i+1)&&count<=n) {
arr[count]=6*i+1;
count++; }
}
printf("%lli",arr[count]);
}}}}
//free(arr);
return 0;
}
int prime(long long int x)
{
int j=1,flag=1;
while(arr[j]<=sqrt(x))
{
if (x%arr[j]==0)
{
flag=0;
break;
}
j++;
}
return flag;
}
The code is working only for n=1,2,3,4, i.e i=0,1,2,3 for which the values are explicitly given. For n=5 onwards it is giving 0 as O/P
There is some glitch related to the global dynamic array as free(arr) is giving core dump error.
Q: Is this the right way to declare a global dynamic array? What could be the problem in this code?
Thank You in advance.
If that is your actual code you have 4 bugs:
2 line comment scopes out a line of your code
the second if should check count < n not count <= n as if count == n you cannot write to arr[count]
You cannot print arr[count] only arr[count-1] which is probably what you mean
In the case where n is less than 4 you still set arr[1], arr[2] and arr[3] which may be out of bounds
It is of course also inefficient to call sqrt(x) in every loop iteration, potentially you should call it outside and there may be a potential rounding issue bug due to the way square roots are calculated, so you might prefer:
while( arr[j] * arr[j] < x )
It would be preferable not to make this global and to pass it into your function.
It would also be preferable to move the main loop logic of your program outside of main().
I'm surprised you say you program works for n=1, 2 and 3 as it looks like you are setting out of bounds.
Your counter goes beyond the size of the array. Specifically both conditions (6i-1 and 6i+1) are met for i=2, and therefore counter is incremented twice, resulting in using arr[5] where you only allocated 5 places in the array. This is because you check counter<=n and not counter
Not sure this could be also be the reason for free creating a core dump, but it is possible (because once corrupting the memory, free may access corrupted data).

floating point:invalid error turbo C

this program takes number of columns as input and should return equivalent amount of numbers of base 3.but in tc it gives a "floating point:invalid" error.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int* count(int);
main()
{
int i,j,n,*a;
printf("n=");
scanf("%d",&n);
a=count(n);
for(i=0;i<pow(3,n-1);i++)
{
for(j=0;j<n-1;j--)
{
printf("%d",a[i*(n-1)+j]);
}
}
return 0;
}
//calculating and storing count values in a 2d array implemented by 1d array.
int* count(int n)
{
int i,j,*a,k;
a=(int*)malloc((n-1)*pow(3,n-1)*sizeof(int));
for(j=0;j<n-1;j--)
{
for(i=0;i<pow(3,n-1);i++)
{
k=(pow(3,n-1-j));
a[i*(n-1)+j]=i%k;
}
}
return a;
}
At this point:
for(j=0;j<n-1;j--)
You loop over the following values:
0, -1, -2, -3, -4, ...
and the loop will (probably) terminate when j wraps around to a positive value. If indeed that's what happens with your long out-of-date compiler.
When you then calculate
pow(3,n-1-j)
The exponent becomes a large positive value and you will overflow in due course.
I expect that's your fundamental problem.
Not sure what you're trying to achieve, but fixing the for loop for j won't crash.
Fix the loop at both places in your code to:
for(j=0;j<n-1;j++)
Most probably it seems you have not linked the math library while compiling your code.

Segmentation fault in C with only certain inputs

Okay, so I'm trying to solve the Knapsack problem.
On small input cases the program runs with no problem and provides the optimal solution, however when the input size is large, or rather the numbers in the input file become large, the program gives me a segmentation fault. I don't quite get why is this happening since the max value of INT exceeds any of these numbers too.
Here's my code.
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int W,n,i,j,k ;
scanf("%d %d",&W,&n); // capacity of knapsack and number of total items
int value[n+1],weight[n+1];
int** A;
A = (int **)malloc((n+1)*sizeof(int*));
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
for(i=1;i<n+1;i++)
{
scanf("%d %d",&value[i],&weight[i]); //taking value and weight of each item
}
for(i=0;i<W+1;i++)
A[0][i]=0;
for(i=0;i<n+1;i++)
A[i][0]=0;
for(i=1;i<n+1;i++)
{
for(j=1;j<W+1;j++)
{
if(j-weight[i]<0)
{
A[1][j]=A[0][j];
}
else
{
if(A[0][j]>A[0][j-weight[i]]+value[i])
A[1][j]=A[0][j];
else
A[1][j]=A[0][j-weight[i]]+value[i];
}
}
for(k=0;k<W+1;k++)
A[0][k]=A[1][k];
}
int max=0;
i=1;
for(i=0;i<2;i++)
for(j=0;j<W+1;j++)
{
if(A[i][j]>max)
max=A[i][j];
}
printf("%d\n",max);
return(0);
}
It runs perfectly for this input http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack1.txt
But when the input size is the one given in the link, it provides a seg fault http://spark-public.s3.amazonaws.com/algo2/datasets/knapsack2.txt
Thanks for the help!
When allocating the arrays for the 2nd dimension you do:
for(i=0;i<W+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));
It should be n+1 instead of W+1 in the loop. You should iterate over the "items" dimensions and allocate "weight" dimension.
The solution will work perfectly for n <= W, but for larger number of items (W < n) - you will get undefined behavior, because you are trying to access A[n][0] at some point, but you did not allocate the array for the nth item.
So basically - you need to change the initialization of the 2nd dimension to:
for(i=0;i<n+1;i++)
A[i]=(int *)malloc(sizeof(int)*(W+1));

Resources