Getting segmentation fault while scanning an integer value - c

Though this is strange, but I am getting a segmentation fault while scanning an integer value.
Here is my program :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int t,n,i,j;
char c;
int grid[1000][1000],right[1000][1000],down[1000][1000];
scanf("%d",&t);
printf("hello\n");
while(t--)
{
scanf("%d",&n);
memset(right, 0, sizeof(int) * 1000 *1000);
memset(down, 0, sizeof(int) * 1000 *1000);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%c",&c);
printf("CHAR = %c\n", c);
if(c == '.')
grid[i][j] = 1;
else
grid[i][j] = 0;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d",grid[i][j]);
}
}
}
return 0;
}
Doing gdb shows segmentation fault at line scanf("%d",&t);. I cannot figure out how this is happening?
[Using gcc-4.8.4 on a linux 32-bit machine ]

The problem is that your arrays: grid, right and down are too big to fit into the stack.
As far as the reason for no compile error is concerned:
Because there is nothing wrong with this code in terms of syntax or semantics. The linker also does not have any problem.
The problem arises when the loader tries to load the program and allocate that much memory on the stack. The stack is usually 8 MB on linux systems and your arrays surpass that.
You can make them static (as suggested in the comments) as static members are allocated on the bss or data segment. But in reality you need to rethink if you need such big arrays.

Set you linker to instruct the loader to allocate a max stack segment limit that is large enough to fit your big local array.

Related

how to resolve the segmentation fault error in the given c program

this is a program to find the maximum occurrence of the largest number in an array.
how to resolve the segmentation fault error in this? hackerrank problem
/* given:
1<n<10^5
1<arrayNum[n] <10^7 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main(){
signed long int max,n,d,a,arrayNum[n];
signed long int max_count; scanf("%ld",&n);
for( a=0; a < n; a++)
{
scanf("%ld",&arrayNum[a]);
}
max = arrayNum[0];
max_count = 1;
for (int a = 0; a < n; ++a)
{
if (arrayNum[a] == max)
max_count++;
else if (arrayNum[a] > max)
{
max_count = 1;
max = arrayNum[a];
}
}d=max_count;
printf("%ld",d);
return 0;}
int main(){
signed long int max,n,d,a,arrayNum[n]; //<< the problem is here,
// the content of n is indeterminate
// at that state
signed long int max_count; scanf("%ld",&n);
...
arrayNum[n] is declared before the value of n is entered by the user.
Just change your code to something like that:
int main(){
signed long int max,n,d,a;
signed long int max_count;
scanf("%ld",&n);
signed long arrayNum[n];
...
There may be other issues though.
And as already stated by others: fix the code indentation. Correctly indentend/formatted code is essential so your code can be understood by others (and even more important by yourself).
To resolve a segmentation fault, the best way is to:
Understand what you do (do you really get what each line of your program does ?).
Fix the errors and warnings given by the compiler.
Compile with debug symbols (-g or -g3) and use a debugger (gdb for example) to find where is your segmentation fault.
First you should check your code indentation, make it more clear for us to read.
Then, give us more information about your segfault : where does it occurs ? You can use tools like Valgrind (on Linux) to find this kind of informations. You just have to build your program with debugging flags (-g on GCC) and run the program with GCC.
The problem here is arrayNum[n] which have the size of a non-initialized variable (n). So this array does not have any allocated space. The access to arrayNum through scanf() create this segfault.

Sieve for 8 digit primes

I am not able to find prime numbers of 8 digits in spite of increasing size of array a. It is working for smaller numbers:
#include<stdio.h>
#include<math.h>
int main()
{
int n,a[100000],i,m,k;
scanf("%d",&n);
for (i=2;i<=n;i++)
a[i]=1;
m=(sqrt(n)+1);
for (i=2;i<=m;i++)
if (a[i]==1)
for (k=i*i;k<=n;k+=i)
a[k]=0;
for (i=0;i<=n;i++)
if (a[i]==1)
printf("%d\t",i);
return 0;
}
I could not get larger than 6 digits either by using the locally declared array. Such an array uses stack memory, which is in short supply compared to heap memory. The other problem is that you didn't check if the value entered for n will break the fixed size array that you declared. I solved both problems by using malloc() to allocate the exact amount of memory required, from the heap, and checked to see if the memory allocation worked.
The other small thing I tidied up was the use of \t to format the output. Once the numbers get large that will look messy. I gave a field width of 10 because that will contain an 8-digit number, also because most text terminals have a width of 80, so the numbers won't break across lines.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,i,m,k;
int *a;
scanf("%d",&n);
if ((a = malloc((n+1)*sizeof(int))) == NULL) {
printf ("Not enough memory\n");
exit (1);
}
for (i=2;i<=n;i++)
a[i]=1;
m=(sqrt(n)+1);
for (i=2;i<=m;i++)
if (a[i]==1)
for (k=i*i;k<=n;k+=i)
a[k]=0;
for (i=0;i<=n;i++)
if (a[i]==1)
printf("%10d",i);
printf("\n");
free (a);
return 0;
}

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

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.

SIGSEGV error keeps showing up

this error keeps on appearing for every program i try to submit on spoj.pl
In the given code i need to find prime numbers between m - n for t no. of test cases .
problem statement:http://www.spoj.com/problems/PRIME1/
the same error is appearing ..
can anyone plss tell me why this error shows up again nd again ..
here's my code
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main()
{
int t;
scanf("%d",&t);
int *m,*n;
m=(int *)malloc(sizeof(int)*t);
n=(int *)malloc(sizeof(int)*t);
int i=0;
while(i<t)
{
scanf("%d%d",(m+i),(n+i));
i++;
}
i=0;
while(i<t)
{
long long int *list,j,k;
list=((long long int*)malloc(sizeof(long long int)*(n[i]+1)));
list[0]=list[1]=0;
for(j=2;j<=*(n+i);j++)
{
*(list+j)=1;
}
float l=sqrt(*(n+i)+1);
//int l=sqrt(*(n+i)+1);
for(j=2;j<=l;j++)
{
if(*(list+j)==1)
{
//printf("\n%ld",j);
for(k=j*j;k<=*(n+i);k=k+j)
*(list+k)=0;
}
}
for(j=m[i];j<=n[i];j++)
{
if(*(list+j)==1)
{
printf("\n%ld",j);
}
}
printf("\n");
free(list);
i++;
}
free(m);
free(n);
return 0;
}
First -- you should not cast malloc -- it can cause unexpected errors.
Second, there's no validation that you allocated the memory you need. There are three different places you're asking for memory and never look to see if malloc returned a NULL result... if t and/or (n[i]+1) is sufficiently large, malloc() may be unable to get a chunk of memory big enough to satisfy the request, in which case you're trying to assign to a NULL pointer and you get a SIGSEGV -- there's a hint given in the description of the problem
Warning: large Input/Output data, be careful with certain languages
(though most should be OK if the algorithm is well designed)
Seems to work fine on my computer, except for the warning about using %ld (%lld should be used). I can only obtain a SIGSEGV error when putting 0 as a value for n[i]. Could you indicate what values you used to generate that error?
Edit :
You are testing for the values "1 888888888 1000000000".
Your computer simply can't allocate an array of such size. You are asking an array of size 1000000001 in your memory. That amounts to about 8GB (since a long long int as about 8B, at least on my computer), which is pretty much undoable for your computer.

How many GB can malloc allocate for your program

I used the following code to find it out but I always get 1 as the answer. is there something wrong. Thanks
#include <stdio.h>
#include <stdlib.h>
int main(){
int mult = 0;
int chk =8;
do{
mult+=1;
int *p = (int*)malloc(1024*1024*1024*mult);
if(p==0){
chk =0;
}else{
free(p);
}
}while(chk !=0);
mult = mult -1;
printf("The number of gigs allocated is : %d\n",mult);
return 0;
}
Just to help, I have a 64 bit system with both windows and linux installed. Thus, is the above logic correct even though I am getting just 1 gb as the answer on a 64 bit system?
If it is a 32-bit OS, then it is not surprising that the largest contiguous block would be 1GB (or somewhere between that and 2GB). On a 64-bit OS, larger blocks would be possible.
If you change your code to allocate smaller individual pieces, you will likely be able to allocate more than 1GB total.
These questions might help you a bit: How much memory was actually allocated from heap for an object? and How do I find out how much free memory is left in GNU C++ on Linux
int main(void){
int MB = 0;
while(malloc(1<<30)){
++MB;
}
printf("The number of gigs allocated is : %d\n",MB);
return EXIT_SUCCESS;
}

Resources