StackOverflowException – What causes this?

ka_vol1_064 Oner Yilmaz Asks:

I am using C# Êxpress developer tool. I Intend to form 3D Mesh object by an array of 60.000 items. When I reach to appr. 19.000 items, I get the error message "An unhandled exception of type ‘System.StackOverflowException’ occurred in Test.exe"
My PC has 2GB RAM.
As for you, what is the reason ?


Well, Oner, you don’t give me a whole lot to go on here but I can explain what is happening and some possible places to look.

There are two places in memory where memory is allocated.  The stack and the heap.  This has been true prior to .NET with languages like C and C++ and it will probably be just as true with future languages.

The heap is where memory gets allocated for objects.  Every time you create a new object in CSharp, you are requesting memory from the heap.

The stack is used to allocate space within a method.  For example, a method such as:

public void Foo()
{
    int i = 0;
    string s = string.Empty;
    s = i.ToString();
    Trace.Warn(s); 
}

In that one call, we set aside memory on the stack for the integer i and for the pointer s.  Yes, s is pointing to an object of type string, but we have to store the pointer to the string some place, that is done on the stack.

The stack for the application is a total of 1 meg.  For most applications that should be more than enough.  Even in your application, it should be enough.

So what happens if we write code like this?

public void Foo()
{
    int i = 0;
    string s = string.Empty;
    s = i.ToString();
    Trace.Warn(s);
    Foo();
}

Anytime Foo() is called, it will just keep calling itself recursively.

In real life, you wouldn’t write code like this.  Well, maybe you would, but it will definitely generate a stack overflow exception.  Normally, you’d probably have this in some sort of loop.

What would happen if we moved the variable declarations into the class instead of the method?

int i = 0;
string s = string.Empty;
public void Foo()
{
    s = i.ToString();
    Trace.Warn(s);
    Foo();
}

Now the memory for those variables will be allocated in the heap when the object this class represents is created.  Our code, in this example, will still generate a stack overflow exception because a small amount of memory is allocated in the stack when the method is called, but it’s not much compared to what we were doing before.

What happens if you create a structure instead?

struct Person
{
    String FirstName;
    String LastName;
    int age;
    Point location;
}

public void Foo()
{
    Person p;
}

In the code above, p is created on the stack because structures are Value types.  This means they do not have to be created with the “new” keyword and they are allocated on the stack, even if you use “new”

Person p = new Person();

 

One other place that will allocate memory off of the stack is in the parameter list.

public void Foo(int age,string firstname,string lastname)
{
    Person p = new Person();
    p.age = age;
    p.FirstName = firstname;
    p.LastName = lastname;
}

Obviously, the more of this you do, the more stack space will get eaten up.

So that’s how you could be using variables that use up the stack memory.  How do you track down what you are doing wrong?

My experience tells me that you are probably making some sort of recursive call and dealing with all of your memory variables inside of the recursive memory.  You probably need to make your variables member variables of the class to prevent the error from occurring.

If it isn’t that, then you need to look for places in your code where you are allocating lots of memory on the stack and find some way of placing it on the heap instead.

Hope that helps.

Related Post

  • Initializing An Array inlineInitializing An Array inline
    This is part two of the discussion I started yesterday about the StackOverflowException, where I explained how memory gets allocated for the different types of variables we have in our systems and...
  • iTextSharp – HTML to PDF – Writing the PDFiTextSharp – HTML to PDF – Writing the PDF
    Last week we parsed the HTML and created code that keeps track of the various attributes we are going to need when we create the PDF.  Today we will finish the code and create the Elements t...
  • .Net String Pool – Not Just For The Compiler.Net String Pool – Not Just For The Compiler
    On Monday, I was corrected in my assertion that creating multiple empty strings would create multiple objects.  Turns out the compiler automatically puts all of the strings that are exactly t...
  • iTextSharp – HTML to PDF – Finishing UpiTextSharp – HTML to PDF – Finishing Up
    In the last post I mentioned there were a few topics we need to close up today.  The two topics we’ve left undone are popping the attribute information off the stack when we hit a closing ele...
  • What is .NET’s Object.GetHashCode() Used For?What is .NET’s Object.GetHashCode() Used For?
    Here is a great question from a visitor. “What is the exact use of GetHashCode of an object in .net? Does it have any relation with garbage collection?” Let's answer the second question first....
  • http://www.commongenius.com David Nelson

    “Every time you say “new” in CSharp, you are requesting memory from the heap.”

    This is incorrect, as you pointed out yourself later on:

    “In the code above, p is created on the stack because structures are Value types. This means they do not have to be created with the “new” keyword and they are allocated on the stack, even if you use “new”.”

Bear