3

when i do this

static void Main()
{
   Main();
}

I receive stackoverflow exception. As i have read so far about C# they say ONLY local variable of value types (and short living ones) will go on stack.

But here in the code there are no local variable to go on stack then what overflows it ?

I know from assembly code line Perspective that reference to Main() will go on stack too ? Is that right ?

Dhananjay
  • 3,673
  • 2
  • 22
  • 20
  • "As i have read so far about C#" I know I havent read much , And also please consider I dont want to improve my C# coding skills by asking this question as i dont have control over stack and heap ... – Dhananjay Mar 20 '12 at 11:26
  • Duplicate of http://stackoverflow.com/questions/1453812/how-to-avoid-a-stack-overflow – Alex Mar 20 '12 at 11:29
  • @Alex : not exactly, i am curious of knowing what else goes on stack as many people says only local variables of value types goes on stack.. so curious if function pointers also resides on stack. – Dhananjay Mar 20 '12 at 11:31
  • @dnkulkarni It isn't just "local variables of value types", in C# "reference" types hide the fact that variables to them are actually value types - these will be held on the stack also with the underling object defined on the heap. – Adam Houldsworth Mar 20 '12 at 11:33
  • yes correct.. i just missed to say that.. i will correct that too. – Dhananjay Mar 20 '12 at 11:34
  • Well, basically what the other thread discussed as well. The return point of the subroutine (in this case Main()) gets stored on the stack, over and over again. – Alex Mar 20 '12 at 11:36

7 Answers7

3

Each time you call main(), the return address is saved in the stack, which will eventually cause your stack to blow up

Shai
  • 25,159
  • 9
  • 44
  • 67
2

A stack frame is pushed to contain the scope of Main even if it is "empty". Also as others have stated, it includes a return address. So yes, you are right.

Anything declared in the scope of a method will be created on the stack (even references to objects), regardless of how long or short-lived they are... as they are guaranteed to live as long as the method scope at most.

Reference types could obviously live longer if the reference is shared outside of the method scope, but the reference within the method scope will still be lost at the end of the method.

You may be looking to try something like implement a Coroutine in C#. Unfortunately the language doesn't offer support for this in its truest sense (Axum used to, because it used linked stacks). Although, that said I've not yet seen it tried using the new C# 5 continuation support.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
2

Each function/method call uses stack to store the return location. Here, you have an infinite recursion which eventually stops because stack space gets exhausted.

zvrba
  • 24,186
  • 3
  • 55
  • 65
2

When you call a function, you have to remember where to go back to, when the function call has ended.

This return address is stored on the stack, this is why you get a stackoverflow with your code.

From the documentation:

A StackFrame is created and pushed on the call stack for every function call made during the execution of a thread. The stack frame always includes MethodBase information, and optionally includes file name, line number, and column number information.

thumbmunkeys
  • 20,606
  • 8
  • 62
  • 110
1

This will cause an infinite loop, which will be why you get your stackoverflow exception.

ianaldo21
  • 679
  • 4
  • 10
1

Stackoverflow

Jon Skeet has a good explanation of why its happening.

(..) this will push a new stack frame for each recursive call to Foo and those stack frames will never be popped, as the calls will never actually return.

Now just replace Foo with Main.

Community
  • 1
  • 1
Alex
  • 7,901
  • 1
  • 41
  • 56
0

This is an example of infinite recursive function. The Stack is pushed every time it encounters a new function call. and never popped out as the stack is never uncoiled. So the stack gets full and results in exception after many call-push cycle.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112