C segmentation fault: 11 - c

#include <stdio.h>
int main()
{
char memf[10000];
int memlen, vn , vw,vh,fattime , posit , speed , interval , nattacks,time=0,qa=0,ninit=0,elxan;
scanf("%d\n",&memlen);
scanf("%d\n",&vn);
scanf("%d %d %d %d %d %d %d",&vw,&vh,&fattime,&posit,&speed,&interval,&nattacks);
while(nattacks>ninit)
{
if(time==fattime)
{
for(elxan=posit;elxan<=posit+vw;elxan=posit++)
{
memf[elxan]=vh;
}
posit=posit+speed;
time++;
ninit++;
}
else if(time>fattime)
{
for(qa=0;qa<100000;qa++)
{
if(ninit==nattacks)
break;
else if(qa%interval==0)
{
for(elxan=posit;elxan<=posit+vw;elxan=posit++)
{
memf[elxan]=vh;
}
posit=posit+speed;
time++;
ninit++;
}
else
posit=posit+speed;
}
}
else
{ time++;
posit=posit+speed;
}
}
/*for(px=0;px<=memlen;px++)
{
if(memf[px]=='0')
memf[px]=1;
}*/
printf("%s",memf);
return 0;
}
I get segmentation fault:11 while executing this code. I know it has something to do with arrays. What is the mistake?

I think this loop is almost guaranteed to run away and access memory outside of the array memf, even assuming that the entered initial values are reasonable.
for(elxan=posit;elxan<=posit+vw;elxan=posit++) {
memf[elxan]=vh;
}
Each iteration tests against posit+vw, but each iteration also increments posit while keeping elxan set to posit's previous value, which unless pathological values for posit and vw are entered, is guaranteed to make the condition always true, and the loop will not terminate within sizeof(memf) iterations.
Once elxan is large enough, accessing memory outside of the declared size of the array is going to cause trouble. While in general you have invoked "undefined behavior" after which nearly anything can happen, the specific symptom of a segmentation fault is very consistent with what we would expect to see eventually from overrunning an array bounds.

Here's how to deal with such an error:
First, add #include <assert.h>. Then, whenever you read from or assign to an array, test first that you are indexing within bounds. E.g., this line:
memf[elxan]=vh;
Should be changed to these lines:
assert(0 <= elxan && elxan < 10000);
memf[elxan]=vh;
This will help you pin-point the error.
You'll notice that you usually don't see so many asserts in other C-programs. That's ok; once you get used to writing C, you'll find you can safely let some of them go. For starters, I think you'll find them very helpful.

Related

Why is these code giving me an sigsegv error?

Why is these code giving me a RUNTIME SIGSEGV ERROR. I have tried running the code and works perfectly in codeblocks but some IDE is giving me these error.
It takes a Fibonacci series then modulus each number in the series and only takes up the numbers at eve places till a single number is obtained.
for example:input 1
9
{0 1 1 2 3 5 8 13 21}->{0 1 1 2 3 5 8 3 1}->{1 2 5 3}->{2 3}->3
#include <stdio.h>
int main(void) {
// your code goes here
int n,j,k,r,o;
o=0;
// printf("enter the number of test cases: ");
scanf("%d",&n);
int s[n];
int a;
a=n;
while(n!=0)
{
r=k;
int e[k/2];
int m;
scanf("%d",&k);//enter say 9
if(k!=1)
{
int i[k];
i[0]=0;
i[1]=1;
for(j=0;j<k;j++)
{
if(j>1)
{
i[j]=(i[j-2]+i[j-1])%10;
}
}
while(r!=1)
{
m=0;
for(j=0;j<r;j++)
{
if(j!=0)
{
if(j%2!=0)
{
e[m]=i[j];
m++;
}
}
}
for(j=0;j<k/2;j++)
{
i[j]=e[j];
}
r=r/2;
}
s[o]=e[0];
o++;
n--;
}
else
{
return 0;
}
}
if(k!=1)
{
for(j=0;j<a;j++)
{
printf("%d\n",s[j]);
}
}
return 0;
}
I want to know which point in the code is trigerring the error i know little about these error(like acessing array beyond bonds) can you explain me that?
Your k variable is uninitialized when you first access it at
r=k;
int e[k/2];
This means that it is equal to whatever happened to be stored at that memory location before. This could be any random number and is very bad.
On the next line you declare an array e[k/2] with size k/2, but since k was never initialized, this could be any size. If k happens to be negative, I get a segmentation fault at that line.
To fix this issue, you need to initialize all your variables before using them.
A segmentation fault (SIGSEGV) is what occurs if you try to access memory that isn't allocated to your program by the operating system.
To help with debugging these errors, run your code in the debugger. This can then take you directly to the line where the segmentation fault occured.
just put the scanf("%d",&k);above r=k;
A SIGSEGV is an error(signal) caused by an invalid memory reference or a segmentation fault. You are probably trying to access an array element out of bounds or trying to use too much memory.
also. i am not sure about the return 0; in the else statement.
i haven't run the code so i may be mistaken but it should be return 1; instead of return 0;
if(j!=0)
{
if(j%2!=0)
{
e[m]=i[j];
m++;
}
}
you can replace it with if(j != 0 && j%2 != 0)
I know this ques you are referring to... This is not how you supposed to solve it... You have to find the number which will left in O(1) time... As the odd places are being removed, we have to worry only about even places... Now those even places may become odd when divided by two repeatedly... Hence there is a fix number of steps which convert the whole array in a single element... At each point of this step even placed number is divided by 2, hence there will be only one even placed number who doesn't become odd placed in between or after these steps... You have to find this number just by looking N, at least i did the same... This is just a hint, if it is unclear , i can explain more logic in comment... Upvote😝

for loop unexceptional behaviour in C

In c programming I write a code as below :
But the problem is first for loop not working properly, means the for loop gets executed only 1 time not t times and some times when first for loop works then output does print yes or no only for l=1 and from l=2 to l=t ,it prints blank screen.
int t,i,n,arr[n+1],j,k,l,flag,x,y;
scanf("%d",&t);
for(l=1;l<=t;l++)
{
scanf("%d",&n);
for(i=1;i<n+1;i++)
{
scanf("%d",&arr[i]);
}
for(k=1;k<n;k++)
{
for(j=k+1;j<n+1;j++)
{
if(arr[k]==arr[j])
{
flag=1;
}
else if(arr[k]!=arr[j])
{
x=arr[k];
y=arr[j];
if(arr[x]==arr[y])
{
flag=2;
printf("YES");
break;
}
}
}
if(flag==2)
{
break;
}
}
if(flag==1)
{
printf("NO");
}
}
This is impossible to diagnose without more context, but here's a huge red flag:
for(i=1;i<n+1;i++)
{
scanf("%d",&arr[i]);
}
You don't show the declaration of arr, but 1-indexing into an array is a very good way of shooting yourself in the foot. Remember that an N-element array in C has valid indexes of 0 to (N - 1), inclusive.
If the above overwrites the array, you get undefined behavior, which of course could make the outermost loop terminate early.
UPDATE: Now that you do show the declaration of arr, we can have a look:
int t,i,n,arr[n+1],j,k,l,flag,x,y;
This is ... very broken, since n is uninitialized at the point where it's being used in the VLA, this gives you undefined behavior. I'm actually a bit surprised your compiler accepted this. I tried building it on ideone.com and it failed, saying:
error: ‘n’ is used uninitialized in this function [-Werror=uninitialized]
Perhaps you should upgrade your compiler too, and make sure you enable all warnings you can since you seem a bit unsure about the very basics of the language.
Another problem is here:
int t,i,n,arr[n+1],j,k,l,flag,x,y;
// ^ ^
// | |--- non initialized n used here
// |
// |-- n declared here bot not initialized
when arr[n+1] is declared, the content of n is undetermined.
You probably want something like this:
int t,i,n,j,k,l,flag,x,y;
scanf("%d",&t);
for(l=1;l<=t;l++)
{
scanf("%d",&t);
for(l=1;l<=t;l++)
{
scanf("%d",&n);
int arr[n+1];
for(i=1;i<n+1;i++)
{
scanf("%d",&arr[i]);
}
...
There are most likely more errors elsewhere. See also the other answer.

SIGSEGV in C error

I always get an SIGSEGV error whenever i am dynamically initializing arrays in C. Please tell me what am I doing wrong all the time?
The code works fine on TurboC but it gives SIGSEGV on an online judge which uses GCC.
Programming Problem
My code:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
long n,h,i,crane=0,box=0,temp=0;
long *comm;
scanf("%ld %ld",&n,&h);
long *a = (long*)malloc(n*sizeof(long));
for(i=0;i<n;i++)
scanf("%ld",&a[i]);
scanf("%ld",&comm[0]);
i=0;
while(comm[i]!=0)
{
i++;
scanf("%ld",&comm[i]);
}
for(i=0;comm[i]!=0;i++)
{
if(comm[i]==3)
box=1;
if(comm[i]==4 && box==1)
{
a[crane]=(a[crane]+1);
temp=0;
}
if(box==1 && (comm[i]==1 || comm[i]==2) && temp==0)
{
a[crane]=(a[crane]-1);
temp=1;
}
if(crane!=0 && comm[i]==1)
crane--;
if(comm[i]==2)
crane++;
if(comm[i]==0)
break;
}
for(i=0;i<n;i++)
printf("%ld ",a[i]);
free(a);
free(comm);
return 0;
}
For a start, nowhere in that code are you actually allocating memory for comm to point to. You apparently know this is required since you've done something similar for a and you free both a and comm at the end.
You need to malloc the memory for comm to point to, before using it. For example, if you wanted that to depend on the second value input (h, probable since it's not used anywhere else), you would need to add in:
comm = malloc(h*sizeof(long));
after the first scanf, noting that I don't cast the return value - you shouldn't do that in C.
If you don't know how big comm should be before using it, the usual way to handle that is to allocate a certain number of elements (the capacity) and keep track of how many you've used (the size). Each time when your size is about to exceed your capacity, use realloc to get more space.
The following (C-like) pseudo-code shows how to do this, starting with an empty array and expanding it by thirty elements each time more space is needed:
comm = NULL
capacity = 0
size = 0
for each value in input():
if size == capacity:
capacity += 30
comm = realloc (comm, capacity), exit if error
comm[size++] = value
Note that, on loop exit, size is the indicator of how many elements are in the array, despite the fact there may be more capacity.
And, as an aside, you should always assume that calls subject to failure (such as scanf and malloc) will fail at some point. In other words, check the return values.

Segmentation error in c program

I am getting segmentation error when trying to do this simple c sorting program
I am a novice in C language . And can you please explain me why i am getting segmentation error
#include<stdio.h>
int main(void)
{
int prev,next,result,total_number;
int i,j=1,b;
int a[i];
printf("Number of values to be entered");
scanf("%d",total_number);
printf(" enter the values \n");
for(i=0;i<=total_number-1;i++)
{
printf(" enter the values \n");
scanf("%d",a[i]);
}
for(i=0;i<=total_number-2;i++)
{
for(j=1;j<=total_number-1;j++)
{
if(a[i]>a[j])
{
b=a[i];
a[i]=a[j];
a[j]=b;
}
else
{
break;
}
}
}
for(i=0;i<total_number-1;i++)
{
printf("The numbers are %d",a[i]);
}
}
The segmentation fault is caused by this line:
scanf("%d",total_number);
You're missing the address of (&) operator, it should be like this:
scanf("%d",&total_number);
The operator is also missing in this line:
scanf("%d",a[i]);
You can find more details on scanf in the glibc manual:
Another area of difference between scanf and printf is that you must remember to supply pointers rather than immediate values as the optional arguments to scanf; the values that are read are stored in the objects that the pointers point to. Even experienced programmers tend to forget this occasionally, so if your program is getting strange errors that seem to be related to scanf, you might want to double-check this.
But there are other subtle errors in your code, too: the fact the int i in array[i] is not initialized leads to undefined behaviour i.e., anything could happen. You can use malloc to allocate space for the array, but a simple reordering could be enough:
scanf("%d",&total_number);
int a[total_number];
Uses user input to allocate the array.
Lastly, it seems like you're trying to implement an insertion sort algorithm, but the logic is slightly flawed: even correcting the bugs in the code the input
1 3 5 0
gets "ordered" to
1 5 3 0
But I don't know what you were trying to implement. In case you were actually trying to implement insertion sort, you could use the pseucode from the insertion sort wiki article to get an idea of what's missing in your implementation.
int a[i]; is creating an array of arbitrary size since i is not initialized.
Instead, you can dynamically create the equivalent of an array of int once you know total_number.
int* a;
. . . snip . . .
/* once you know total_number */
a = (int*) malloc(total_number, sizeof(int));
/* you can use a with array notation as long as you stay in bounds */
a[i] = something;
/* don't forget to free a when you are done */
free(a);

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.

Resources