Segmentation fault when calling functions recursively - c

I'm writing a program that prints infinite numbers.
#define false 0
#define true 1
int test(int idx) {
printf("%d\n",idx);
test(idx+1);
return 0;
}
int main() {
test(0);
return 0;
}
// Segmentation fault: 11
This program ended with a segfault after printing 262045.
I understand it is caused by stack overflow.
Is there any clever trick that can make the recursion go deeper?
Like calling another recursive function when it reaches a certain number and clears the stack?
I tried doing this.
#define false 0
#define true 1
int test2(int idx) {
printf("test2 here\n");
printf("%d\n",idx);
test2(idx+1);
return 0;
}
int test(int idx) {
if (idx == 262000) {
return test2(idx);
}
printf("%d\n",idx);
test(idx+1);
return 0;
}
int main() {
test(0);
return 0;
}
But the stack is not cleared. There is still a segfault after printing 262044.

In the first snippet, you're hitting a stac overflow.
In the second case, it invokes UB because of signed integer overflow.

Related

Unlocks all pthread mutexes in mutex array

Im trying to write a function that unlocks all pthread mutexes provided in an array of mutexes.
The array is mutexv and the number of mutexes in given by mutexc.
The function should return 0 on success,
-1 otherwise.
my function so far:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <alloca.h>
#include "pthread.h"
#include "multi_mutex.h"
int multi_mutex_unlock(pthread_mutex_t **mutexv, int mutexc)
{
(void) mutexv;
(void) mutexc;
pthread_mutex_init(*mutexv, NULL);
for (int i=0; i<mutexc; i++){
if (pthread_mutex_unlock(*mutexv) !=0){
return -1;
}
}
return 0;
}
having a hard time figuring out what im doing wrong.
// correct type for specifying array sizes is size_t, not int:
int multi_mutex_unlock(pthread_mutex_t **mutexv, size_t mutexc)
{
// you wouldn't initialize here, that needs to occur much earlier
//pthread_mutex_init(*mutexv, NULL);
for (size_t i = 0; i < mutexc; i++)
{
if (pthread_mutex_unlock(mutexv[i]) != 0)
// you need to index properly ^^^
{
return -1;
}
}
return 0;
}
Actually a while loop can be more elegant:
int multi_mutex_unlock(pthread_mutex_t **mutexv, size_t mutexc)
{
while(mutexc)
{
if (pthread_mutex_unlock(*mutexv) != 0)
{
return -1;
}
mutexc--; // decrement the remaining number
mutexv++; // increment the pointer to point to next mutex
}
return 0;
// or totally compact as:
for(; mutexc; --mutexc, ++mutexv)
{
if (pthread_mutex_unlock(*mutexv) != 0)
{
return -1;
}
}
}
Finally: You don't give any information on how many mutexes actually could be unlocked (or alternatively, how many have not) – you might return that number instead of -1, then any value different from originally passed mutexc would mean an error occurred.

Why isn't main() returning any value?

/I am trying to return the 1st bit of boolean value of 10 using right shift in the cb function./
#include<stdbool.h>
bool cb(int N,int i){ //`called function`
return ((N>>i)&1)==1;
}
int main(void) { //`main function`
cb(10,1);
return 0;
}
//Status:successfully Executed,but no output.
main doesn't magically return the result of another function, you need to return the value also from main
int main(void)
{
return cb(10, 1);
}
or you can exit the program from your function with a value:
bool cb(int N,int i){ //`called function`
exit(((N>>i)&1)==1 ? EXIT_FAILURE : EXIT_SUCCESS);
}
and check the return in the console:
./yourprogram
echo $?
But notice that this is considered bad practice, we usualy return EXIT_FAILURE only when something went wrong, instead, you can print the result:
int main(void)
{
printf("%d\n", cb(10, 1));
return 0;
}
Finaly, you can use a debugger
Change your code to
Line 6 int res = cb(10, 1);
Line 7 return 0;
and start the debugger
gdb yourprogram
breakpoint 7 (after the line you want to inspect)
run
print res
So Here's your program:
#include<stdbool.h>
//`called function`
bool cb(int N,int i)
{
return ((N >> i) & 1) ==1;
}
//`main function`
int main(void)
{
cb(10,1);
return 0;
}
Your program is executing - which means that the main() function is returning successfully (a Value of 0). You also invoke cb(10,1); which calls your function declaration above (and returns a boolean: True/False). But you don't store the value of that function call, nor display the value with a printf() or cout statement.
You'll need to add more for your program to give you more noticable output.

Recursive function is not working with a pointer

This function aims to return the number of zeroes in a number, num. The function rCountZeros2() passes the result through
the pointer parameter result.
`
void rCountZeros2(int num, int *result)
{
if (num==0)
return;
else
{
if (num%10==0){
(*result)++;
}
rCountZeros2(num/10, result);
}
}
`
See when you are invoking rCountZeros2() , my guess is value in variable result is not zero.It may be some garbage value or some other value from previous computation.However with details you have provided it is difficult to provide exact answer.
Kindly try the following standalone program, I got correct answer using your code
void rCountZeros2(int num, int *result)
{
if (num==0)
return;
else
{
if (num%10==0){
(*result)++;
}
rCountZeros2(num/10, result);
}
}
int main()
{
int result = 0;
int num=12300000;
rCountZeros2(num, &result);
printf("number of zeros in %d = %d",num ,result);
}

Segmentation fault on deleting an element after searching it in a heap

The following code deletes an element x from a heap after searching it linearly in the heap
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MaxSize 100001
struct minheap {
long int a[MaxSize];
int end;
};
void minHeapify(struct minheap *h, int i) {
int largest;
long int temp;
int l=2*i+1;
int r=2*i+2;
largest=i;
if(l<=(h->end) && (h->a[l])<(h->a[i]))
largest=l;
if(r<=(h->end) && (h->a[r])<(h->a[largest]))
largest=r;
if(largest!=i) {
temp=h->a[i];
h->a[i]=h->a[largest];
h->a[largest]=temp;
minHeapify(h,largest);
}
}
int main() {
long int x,i=0,temp=0;
int N;
int type;
scanf("%d",&N);
struct minheap h;
h.end=-1;
while(N--) {
scanf("%d",&type);
if(type==1) {
scanf("%ld",&x);
h.end=h.end+1;
h.a[h.end]=x;
i=h.end;
while(i>0 && h.a[(i-1)/2]>h.a[i]) { //fix minheap on insertion
temp = h.a[(i-1)/2];
h.a[(i-1)/2]=h.a[i];
h.a[i]=temp;
i=(i-1)/2;
}
}
else if(type==2) {
scanf("%ld",&x);
for(i=0;i<=h.end;i++) {
if(x == h.a[i])
break;
}
h.a[i]=h.a[h.end];
h.end=h.end-1;
if(i!=(h.end+1))
minHeapify(&h,i);
}
else if(type==3) {
printf("%ld\n",h.a[0]);
}
}
return 0;
}
But the following test case gives segmentation fault as:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 main () at solution.c:59
59 if(x == h.a[i])
#0 main () at solution.c:59
The entire test case can be found on this link:
https://hr-testcases-us-east-1.s3.amazonaws.com/15379/input04.txt?AWSAccessKeyId=AKIAJ4WZFDFQTZRGO3QA&Expires=1547134261&Signature=D%2B39%2BHr%2F4lRFV%2BetxFwnGWm1iac%3D&response-content-type=text%2Fplain
Why is this segmentation fault occurring?
Given the error message,
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0 main () at solution.c:59 59 if(x == h.a[i])
> #0 main () at solution.c:59
...the value i in the expression: if(x == h.a[i]) is probably out of bounds. This leads to undefined behavior, which in some cases might seem to work, other might lead to a segmentation fault.
Look at this line for a possible the solution:
for(i=0;i<=h.a[h.end];i++)
What is the value of a.end at the time this expression is called?
There is also a potential for problems here:
while(i>0 && h.a[(i-1)/2]>h.a[i])
Where the expression: (i-1)/2 is integer division, and will skip values.
I see a few problems in your code to delete an item:
for(i=0;i<=h.end;i++) {
if(x == h.a[i])
break;
}
h.a[i]=h.a[h.end];
h.end=h.end-1;
if(i!=(h.end+1))
minHeapify(&h,i);
First, if an item with the value you entered is not found, you're going to have trouble because i > h.end. You'll end up either indexing off the end of the array, or deleting the last item.
More importantly, you're not handling the case where the item you replace it with is smaller than the parent. For example, consider this heap:
1
6 2
7 8 3
If you delete the node with value 7, the value 3 replaces it:
1
6 2
3 8
That's not a valid heap. You have to move the 3 up in the heap to create:
1
3 2
6 8
The key here is that if the item you're replacing is in a different subtree than the last item in the heap, it's possible that the replacement node will be smaller than the parent of the replaced node.
So your code has to do this:
h.a[i] = h.a[h.end];
h.end = h.end-1;
// here you have to:
// if (h.a[i] < parentOf(h.a[i]))
// move it up the heap
// else
// minHeapify(&h, i);

Segmentation fault (core dumped). Heapsort

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.

Resources