Why is these code giving me an sigsegv error? - c

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😝

Related

Debug-print for loop omitting 1st value

I was debugging a low level program, I had to ensure that my array exp have all values I expect it to have. So I wrote a code snippet that prints my array to help debug it. Problem is standard library isn't available so I need to use my own code.
My code snippet:
int test=0;char val[5]={};
int l=0;
for(int k=0;exp[k]!=0;k++)
{
test=exp[k]; //taking in value
int_to_ascii(test, val);
print_char(val,2*l,0xd);
for(int m=0;val[m]!='\0';m++)//clearing out val for next iteration
val[m]='\0';
l=k*0xA0; //next line
}
exp is an integer array..
code for int_to_ascii:
if(src==0)
{
stack[i++]='\0'; //pushing NULL and 0 to stack
stack[i++]='0';
}
else
{
while(src!=0) //converting last digit and pushing to stack
{
stack[i]=(0x30+src%10);
src/=10;
i++;
}
}
i--;
len=i;
while(i>=0)
{
dest[len-i]=stack[i]; //popping and placing from left to right
i--; //inorder not to get reversed.
}
print_char works because I use it to print entire window and interface. It basically takes
char* szarray,int offset,int color.
I was yelling at my computer for nearly 2 hours because I thought my array is incorrect but it shouldn't be, but the actual problem was in this debug code.It doesn't print exp[0].
When it should output:
20480
20530
5
It just prints
20530
5
I even tried brute forcing values into exp[0]. If I give any value except 20480 into that, it will print invalid characters into first entry,like this:
20530P\. ;not exact value, demonstration purpose only
5
I think something is off in int_to_ascii, but that also is extensively used in other parts without any problems.
Any one have any idea with it?

Segmentation Fault in Mergesort While assigning an array - c

I have written a Merge Sort program in c but getting a segmentation fault. After trying to debug my code i got to know the particular line in which i am getting the error but i wanted to know what is the reason??
Here is my code:
void Mergesort(struct record r[],int n)
{
int k;
if(n>1)
{
int i,j;
struct record r1[n/2];
struct record r2[n/2];
for(i=0,j=n/2;i<n/2,j<n;i++,j++)
{
r1[i]=r[i];
r2[i]=r[j]; // this is the line where i am getting the error.
}
Mergesort(r1,n/2);
Mergesort(r2,n/2);
r=Merge(r1,r2,r,n);
}
}
struct record * Merge(struct record r1[],struct record r2[],struct record r[],int n)
{
int i=0,j=0,k=0;
while(i<n/2 && j<n/2)
{
if (strcmp(r1[i].a,r2[j].a)<=0)
{
r[k]=r1[i];
i=i+1;
}
else
{
r[k]=r2[j];
j=j+1;
}
k=k+1;
}
if(i==n/2)
{
for(j;j<n/2,k<n;j++,k++)
{
r[k]=r2[j];
}
}
else
{
for(i;i<n/2,k<n;i++,k++)
{
r[k]=r1[i];
}
}
return r;
}
One more thing : I am getting segmentation fault only when the no. of entries which i want to sort are not a power of 2. The code is running properly for entries such as 2,4,8,16.
The error is because when you have odd number of entries, you under allocate.
Example:
when n = 7, n/2 is 3. so you have both r1 and r2 of size 3 for a total of 6. In the for loop, the i is less than 3 (i.e, 0,1,2) and j has initial value 3 and max value 6 (so 3,4,5,6). so j needs 4 but r2 has only memory for 3 elements. So, it crashes.
It does not happen for powers of 2, because even when you divided the array by 2, they still remain powers of 2 and even except for 1. When there is only one element, you don't have to do anything.
I think you need to allocate n - n/2 for r2.
Certainly an error because the multiple conditions of the for loop separated by a comma: the condition i<n/2 is simply ignored. See here for details.
For n==3 you get n/2 == 1 and you have no place to store all 3 items. The simplest solution (can't say if the best one) is to use n/2 and n-n/2 to size sub-arrays.

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.

C segmentation fault: 11

#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.

What happens when you write to memory out of bounds of an array?

On a recent test question I was asked to print the output of the following program. I got the answer correct however this program caused me significant mental anguish as I didn't know what the behavior would be when writing to memory that is out of bounds of an array.
Here is the program under question, the comments are my notes:
#include <stdio.h>
#define MAX 4
void RecordArgs(int x);
int main()
{
RecordArgs(1);
RecordArgs(7);
RecordArgs(-11);
return 0;
}
void RecordArgs(int x)
{
static int i = 0;
int call_count = 0;
int arg_history[MAX] = {0};
if (call_count == MAX)
{
# call_count is not static and is initialized to 0 on each call
# as a result, under no circumstance can call_count == MAX and
# this printf is never executed
printf("Too many calls to RecordArgs\n");
}
else
{
# index out of bounds on second/third call (i + call_count will be 4??)
arg_history[i + call_count] = x;
++call_count;
++i;
for (i = 0; i < MAX; ++i)
printf("%d ", arg_history[i]);
printf("\n");
}
}
And the expected output:
1 0 0 0
0 0 0 0
0 0 0 0
When RecordArgs is called the second and third times where does the 7 and -11 values get written? I tried compiling it under different settings to see if I could get it two write to something it shouldn't but everything I've tried has resulted in that exact output w/o any segfaults.
Expanding on Patashu's comment, segmentation faults occur when you access memory from a page in a way which clashes with the page of memory's permissions. In other words, they occur when you access a page of memory in a way that you're not allowed to. What's possibly occurring in your situation is that you are accessing memory still within the same page on which arg_history is stored, for which you obviously have permission to read and write.
Another possible scenario is that the page of memory right after the one you're working on has the same permissions which allow you to access it the same way.
In any case, this is undefined behavior in C. Although you witness "expected results," that should not indicate to you that the program is correct. In fact, this is a circumstance in which an out-of-bounds error could potentially go unnoticed, if it doesn't cause a segmentation fault.

Resources