C program recursive call to main() with and without parameters - c

Why does it give an error of segmentation fault(core dumped) and gives no output in 1st case ?Can anyone explain how program is program callls main recursively with parameters?
#include <stdio.h>
int main()
{
static int i = 2;
if (i<7)
{
main();
printf("%d ", i);
i++;
//main(10);
}
}
-
#include <stdio.h>
int main()
{
static int i = 5;
if (--i)
{
//main();
printf("%d ", i);
main(10);
}
}

You are calling main() first and then incrementing i
if (i<7)
{
main(); // <-- main called when i still 2
printf("%d ", i);
i++; // <-- statement never reached
//main(10);
}
Hence, while main() calls main() recursively, the statement i++ is never reached.
You should increment i before calling main()
if (i<7)
{
i++;
main();
printf("%d ", i);
//main(10);
}

1st case the i++ after the call of main(), that means the program has no chance to add the i, and into infinity loop, and stackoverflow! haha....
but the 2nd case, it's reduce the i before you call the main.

TL;DR StackOverflow (Pun or no pun, it's true both ways).
First: Some important information
This case has nothing to do with passing an argument to main() or not. Actually, as per the latest C standard, C11, for a hosted environment, the conforming signature of main() is int main(void) and following that, main(10); is wrong, altogether.
Now, coming to the actual problem here,
In the first case, change of i value happens after the call to main(), so in effect, the value of i never get changed because the control never reaches the statement which modifies i. Hence, it's an infinite loop, and because of the recursive call to main(), stack overflow happens.
In later case, i value gets updated before call to main(), so that value actually reflects. Thus, at some point (after 4 occurrences, actually), the if condition meets a FALSE condition and the recursive call ends and the stack unwinds.

First case:
i++ is positionned after the call to main. So i will always be equal to 2, as you never reach this part of the code. You are then calling your main function everytime, leading to an infinite recursion, and thus to the segmentation fault. The fix for this case would be to increase i before calling the main function.
if (i<7)
{
i++; // Increment before calling the main function, so i value is changed
main();
printf("%d ", i);
}
Do note that it will lead to something which looks like your second case, except that you will print several "7".
Seconde case:
In the second case, you are decreasing the value of i everytime you enter your if condition. When you finally can't enter your if condition anymore, it means i is equal to 0 (as if(0) is equivalent to if(false)). Everytime you will return to the previous called main function, i will still be equal to 0, explaining why you are displaying "0" everytime. If you want to print the different values, you can place your printf before the call to the main function for instance.

In the first case:
"i" is never incremented therefore you run in an infinite loop and get an overflow.
In the second case:
You call the recursion before displaying the value of "i", after four calls "i" equals to 0 and your recursion stack unwinds.
Modify your condition and perform outputs before the recursion call.

In the first case, i is never incremented, hence, the main keeps getting called and soon enough there is no more stack memory available to the program.
In the second case, the last updated value of i is intact throughout the lifetime of i. As i is static, program is referring to the same memory address on all the iterations. While printing i you see the last updated value, that is 0, as output.

Related

return value 3221225725 while experimenting with simple recursive function

While studying pointers, I was experimenting with the following simple recursive code.
#include <stdio.h>
void test(void);
int main(void)
{
test();
}
void test(void)
{
int i = 4;
printf("%i %i\n", &i, i);
main();
}
output
...
4345292 4
4345228 4
--------------------------------
Process exited after 7.041 seconds with return value 3221225725
Press any key to continue . . .
Why it returns to value 3221225725. Does C run out of memory to store?
I was wondering why It only breaks after exact 32455 loops
(i am still in a learning phase, This is an experiment not actual code for any use. I purposefully made it break.)
The return value 3221225725 (C00000FD in hexadecimal) is the error code for stack overflow on Windows.
The stack overflow happens because your recursion never stops. main is calling test which is calling main which is calling test and so on indefinitely until the process' stack is full and then Windows kills the process and returns the error code to the caller.
If you want to use recursion, you need a stop condition so the recursion will end at some point. Google "factorial recursion" for a simple example.
Be aware that recursion can be abused and often an iterative approach is more efficient.
First of all, in the part
printf("%i %i\n", &i, i);
by supplying a pointer type as the argument of %i, you're invoking undefined behavour.
Change the code to
printf("%p %i\n", (void *)&i, i);
That said, calling main() recursively is not a very good idea. Then, it's an infinite recursion, so you'll eventually encounter a stack overflow.
Use a loop if you want some actions to be repeated, with a proper terminating condition.

Can someone explain output of this C program? [duplicate]

This question already has answers here:
unexpected output in C (recursion)
(3 answers)
Closed 4 years ago.
#include <stdio.h>
int main()
{
static int i = 5;
if (--i)
{
main();
printf("%d\n", i); // will this line executes ?
}
return 0;
}
Output:
0
0
0
0
does code below main(); printf statement instructions is placed to stack every time when main recursive calls happens and executed while terminated from this program?
i is reduced by successive calls to main until zero is reached.
Then printf is called for each level of recursion.
(Note that the behaviour of calling main from itself is well-defined although ill-advised in C, in C++ the behaviour is undefined.)
if (--i)
This will evaluate true the first time (--i == 4). The code recurses into main(). (Recursion: A function calling itself.)
As i is static, it will retain its value of 4 (as opposed to an automatic variable, which would be initialized to 5 again). The if (--i) in this second execution of main() will again be true (evaluating to 3), and will again call main() (for a third execution of the function).
The same for --i == 2 and --i == 1, for four executions of main() (including the first, non-recursive one) total that are evaluating the if condition to true.
The next recursion will evaluate the if condition to --i == 0, and thus false. Skipping the if clause, the function call will just return. i is zero at this point, and -- being static, i.e. only one persistent i for all instances of main() -- will remain at that value.
The main() call one level up the stack -- the one that evaluated --i == 1, then called main() and was waiting for it to return -- will now continue with the statement after the call to main(), and printf() the current value of i... which is 0.
The same happens three more times (for a total of four) until the top-most main() returns. You get four times the current value of i, which is 0.
Note that calling main() from your program is allowed in C, but not in C++. This is specifically for calling main() recursively; for other functions, it is allowed in either language.
(--i) will decrease the value of i to 4 when it is called for the first time and it will continue the decrement of i until (i==0) due to recursion.
Since you have declared the variable i with static keyword and hence a single memory is allocated to it and all the changes are reflected back to it

difficulty in understanding successive recursive calls

I am trying to understand the following program in which successive recursion function calls are present, but getting confused while tracing how the tack gets loaded.
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[]){
if(a[1]=='\0')
return;
func(a+1);
func(a+1);
printf("%c",a[1]);
}
the output for this is 3 3 2
would appreciate if someone could advise on this one...
does this kind of multiple recursive calls beneficial in any way or find application in specific problem areas..?
Just put yourself in the position of the CPU and step through line-by-line (or use a debugger to help with that task).
The first call is to
func("123")
this call does not satisfy the termination condition a[1] == '\0', so it calls
func("23");
The call to func("23") in turn calls
func("3")
which DOES satisfy the return condition. So, that call returns to the previous caller, func("23").
func("23") proceeds to make another call to func("3") due to the lines
func(a+1);
func(a+1);
Continue this process of executing the program in your mind, and write down what would be in each call to printf. That will explain your output.
UPDATE
Note that the call to printf() happens after the recursive calls, so e.g. a call to
func("123")
would proceed like
Enter func("123")
Termination condition not met
Call func("23")
Call func("23") again
Printf("3") (which is a[1])
Return
Debugging with breakpoints is one way to understand recursion. Another way is to draw the tree of recursive calls.
From the figure, In every level after level0, the printf statement occurs after every two nodes owing to these two lines of code:
func(a+1);
func(a+1);
In general, this becomes a perfect binary tree for any input string of length greater than 0. The total number of nodes is given by this formula:
2^(k+1) - 1 // k is the depth; here k = 2
Total number of printf statements executed can be obtained by this formula:
2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively
the posted code is a rather poorly designed instance of recursion.
The following code has the correct 'tail' form of recursion.
It could be made even better by passing the reversed string back to main and let main print it.
It reverses the order of the string passed to func() by main()
Please, when asking about a runtime problem, post code the compiles, including the necessary #includes for header files so we are not guessing about which headers to include
#include <stdio.h>
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[])
{
if(a[1]=='\0') // check for end of recursive sequence
{
printf( "%c", a[0] ); // last tail action
return;
}
func(a+1); // step+next recursion
printf( "%c", a[0] ); // tail action
return;
}
The recursion can be simply understood as follows.
For example:
Func(int a){
while(a>1)
return a * func(a-1);
}
Suppose a = 5.
What happens is that it returns 5 * func(4).
Now func(4) returns 4 * func(3) and it goes on like this.
Check out this example for use of recursion in fibonacci series.

Unpredictable output of recursion of main()

The following code gives output as 0 0 0 0 using Codeblocks.
int main()
{
static int i=5;
if(--i){
main();
printf("%d ",i);
}
}
I perfectly understands how the above code executes. However, when I removed 'static' from the code and used int i = 5, Ideone.com(online compiler) gave me runtime error and Codeblocks(using GCC) gave me nothing- even the terminal does not pop up.
I also tried placing the declaration part outside main i.e., static int i; and in main, I then gave i = 5;. Still, I am getting the above errors. I have no idea what is happening. Any help would be greatly appreciated.
PS: The program was found on a website and no explanation was given there.
If you remove the static that each call to main gets its own copy of i, initialized to 5, and so your recursion never terminates.
When you declare static int i outside main() and initializing it inside main() to value 5 has a problem when you execute. For the first time if(4) makes it call your inner main() which executes outer main() making i set back to 5 leading it to infinite loop, hence no output you see because your if never fails and only one possibility it has is if(4).
int main() // 1st main call
{
static int i=5;
if(--i){ // if(4), if(3), if(2), if(1)-> all four if's are true
// if(0) fails
main(); // 2nd main, 3rd main, 4th main, 5th main -> corresponding to
// above successful if's.
// When if(0), recursion ends, return
printf("%d ",i); // Now i is `0` and prints 4 zero's
}
}
If you remove static, you get an infinite recursion before you output anything. The recursion leads to a stack overflow, and the program crashes.
The static means you operate always on the same variable, so you can count from 5 -> 0. if you remove it, you initialize it at every call with 5, and if(4) is always true.
With static it is only initialized once.
when using static printf will show 4,3,2,1 and the recursion will end.
when not using static, theoretically (if the program would run) the printf will show 4,4,4,4..
and the recursion will never end.
There is no problem in your code.
CASE 1:
if you write, it will give you output 0000 cause very time the you are decrementing the value of i. once it become 0. if condition will be false and it will print 0 four times.
int main()
{
static int i=5;
if(--i){
main();
printf("%d ",i);
}
}
CASE 2:
but if you remove the static, the in every recursive call you are creating a new variable i which will take 2 byte each time and consume memory(in stack). Once the stack full, it prompt runtime error and program will be crashed. The online compiler of http://ideone.com
handle the runtime error in backend so that your program will not crashed.that why you are getting runtime error. and expected answer.
CASE 3:
and when you declare your variable outside like
static int i;
int main()
{
i=5;
if(--i){
main();
printf("%d ",i);
}
}
In this case it will again cross the memory limit. here each time you are assigning the 5 to i and main() will take space in stack, again program crash.

Explain the output of a c program

#include<stdio.h>
main()
{
static int i=1;
printf("\nSoftware");
for(;i<5;i++)
main();
return 0;
}
The output comes out to be an infinite loop. Please explain.
You are calling a main function from your main function. After you call new main function it will print some string and then again it will call main function.
Your i variable will not be incremented at all, because it is not incremented in the first iteration of for loop. After you call main, it will never return to previous main to next iteration of for loop to happen. So the loop will be infinite and i will be equal to 1. Even if you changed the for loop to any other loop, the loop will be still infinite.
I'm including your repaired code, just for the fun of it:
#include<stdio.h>
int main()
{
static int i=0;
if(i>=5) return 0;
i++;
printf("\nSoftware %i", i);
main();
return 0;
}
When one iteration of Loop finishes then value of i is incremented. But in your case before increment it is again calling the main() function. Hence your Code is in infinite loop.
It is not an infinite loop.
Your are recursively calling main but never give an end to it. This results in a stack overflow.
i++ is never evaluated, because you never reach the end-of-scope of the for loop.
This isn't seem to be any difficult or different.In this program for loop do not matter much, so whenever a main() is called inside the same it is definitely a infinite loop.With use of Conditional statements you can restrict the infinite loop. Also that static int do not matter at all.So obviously main get called infinite number of times until time out occurs.
This is infact self explanatory
Calling main function in a loop eats up all your memory and causes stack overflow.
Yeah definitely the output comes out to be infinite because in for(;i<5;i++) the increment of i occurs only at the last line of the for loop. So, here the value of i never incremented.
for example:
for(i=0;i<5;i++)
{
int a,b; // just an example
a=10;
b=20;
printf("%d",i);
printf("%d %d",a,b);
// increment of i takes place here at the last line of for loop
}
Same as here also:
main()
{
static int i=1;
printf("\nSoftware");
for(;i<5;i++)
{
main();
// increment of i takes place here.But compiler never comes at this line .That's why i never incremented .
}
return 0;
}
the code call main function, again and again
for(;i<5;i++)
main();
i<5 call main()
i<5 call main()
i<5 call main()
...
If u want to call some function 5 times.
include
void myFunc()
{
printf("\nSoftware");
}
main()
{
static int i=1;
for(;i<5;i++)
myFunc();
return 0;
}
Im used to c++ so it could be a some small mistake.
Its a kind of Recursive Call. Your main function is calling itself resulting into an infinite loop.

Resources