Stackoverflow exception occurs when a method is called recursively(infinite times)(different stack frames are allocated to each recursive call,Multiple stack frames are used in this case).As we know a stack frame is allocated to each method call.can the stack be overflown with using single method (using single stack frame).
Asked
Active
Viewed 131 times
2
-
3_"a superate stack frame is allocated to each method"_ - this is incorrect. A stack frame is allocated for each method _call_. The most common cause of an overflow is a method calling itself without a suitable break condition. – ProgrammingLlama Jan 10 '20 at 06:42
-
1"when a method is called recursively(infinite times)" - it doesn't have to be infinite - just "too many" – Marc Gravell Jan 10 '20 at 07:13
-
See also [this question](https://stackoverflow.com/q/59528181/15498) – Damien_The_Unbeliever Jan 10 '20 at 08:02
-
ok cool,many times – Nikhil Chitneni Jan 10 '20 at 08:09
1 Answers
4
can the stack be overflown with using single method
Sure:
static unsafe void Main()
{
for(int i = 0; i < 50; i++)
{
// fails on i=18 for me
long* ptr = stackalloc long[10 * 1024];
}
}
A stack overflow happens when the stack is fully consumed. There are multiple ways to do that; recursion is just one of them. stackalloc
creates a pointer to (or more recently: a span over) a block of memory at the current stack-frame, extending the current stack-frame; it will be conceptually reclaimed (although in reality, this just means changing a single number) when you return (or throw, etc) from the method that allocated it.
Another way would be to create an absurdly over-sized value-type:
static class P
{
static void Main() => Foo();
static void Foo() => Bar(default);
static void Bar(FatStruct2097152 a) => Console.WriteLine(a);
}
struct FatStruct64 {
private long a, b, c, d, e, f, g, h;
}
struct FatStruct512 {
private FatStruct64 a, b, c, d, e, f, g, h;
}
struct FatStruct4096 {
private FatStruct512 a, b, c, d, e, f, g, h;
}
struct FatStruct32768 {
private FatStruct4096 a, b, c, d, e, f, g, h;
}
struct FatStruct262144 {
private FatStruct32768 a, b, c, d, e, f, g, h;
}
struct FatStruct2097152 {
private FatStruct262144 a, b, c, d, e, f, g, h;
}

Marc Gravell
- 1,026,079
- 266
- 2,566
- 2,900
-
[How to change stack size for a .NET program?](https://stackoverflow.com/questions/2556938/how-to-change-stack-size-for-a-net-program) can be used to let less dramatic (not `unsafe`) ways to achieve it fast enough too. – Alexei Levenkov Jan 10 '20 at 07:14
-
Mark - Nice! I did not remember if there is a limit on `struct` size and if there is one how far it from default stack size so though you'd need to shrink stack anyway... but too lazy to try right now :) – Alexei Levenkov Jan 10 '20 at 07:24
-
1My reaction to this abomination (FatStruct, of course) is essentially [this scene from Jurassic Park](https://media.giphy.com/media/37Fsl1eFxbhtu/giphy.gif) – ProgrammingLlama Jan 10 '20 at 07:31
-
so now stack memory is the collection of stack frames memory.if a new method is called a stack frame is allocated,what is the actual meaning of this ?(is it allocating the next block to the new method call?) – Nikhil Chitneni Jan 10 '20 at 08:33
-
1@NikhilChitneni stack frames aren't "allocated" as such - the stack is just a contiguous chunk of memory; there are no blocks - it is just a chunk of virtual memory; a method call simply takes the space required for the target and parameters, (some amount) of space for the book-keeping, (some amount of space) for the locals declared by the method, and then it just increments (technically, decrements - the stack grows downwards, because reasons) the pointer to the current semantic frame within that space – Marc Gravell Jan 10 '20 at 11:29
-
what is the point calling in it as a frame?we are just allocating the memory in a sequence (i mean is there no such thing as a frame for methods,even for different method calls the stack memory is allocated contigiously right?) – Nikhil Chitneni Jan 10 '20 at 11:46
-
@NikhilChitneni I don't understand the question; can you rephrase it? – Marc Gravell Jan 10 '20 at 11:59
-
how can we differentiate from 1 frame to another ? (do frames have any starting and ending points so they can be differentiated ?) – Nikhil Chitneni Jan 10 '20 at 12:03
-
@NikhilChitneni I *expect* that it uses ESP/EBP, since that is what they are designed for... https://stackoverflow.com/a/21718937/23354; the details for how call semantics are handled are complex, and frankly not very interesting to me - they're pure runtime implementation details that you shouldn't need to care about unless you're writing / maintaining the runtime or JIT itself; however, my understanding is that somewhere between EBP and ESP is the return pointer that points to the *previous* stack location. If you need to know these details in C#: you're doing something very wrong. – Marc Gravell Jan 10 '20 at 12:07
-
Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205750/discussion-between-nikhil-chitneni-and-marc-gravell). – Nikhil Chitneni Jan 10 '20 at 12:41
-
if we are calling a recursive function,are the last instruction of the first call of method and the first instruction of the second call stored in a sequential way ? this is what i actually wanted to know – Nikhil Chitneni Jan 10 '20 at 13:01
-
@NikhilChitneni assuming that the JIT doesn't choose to implement it as a tail-call (overwriting the current stack-frame), then there's nothing special about recursive calls - they're just the same as any other call, one after the other. So whatever "special way" is used: it is the same "special way" as any regular call. – Marc Gravell Jan 10 '20 at 13:32