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...
  • Date Change For “TESTING WEB APPLICATIONS WITH SELENIUM, NUNIT AND .NET”Date Change For “TESTING WEB APPLICATIONS WITH SELENIUM, NUNIT AND .NET” Last week I mentioned that I will be presenting “TESTING WEB APPLICATIONS WITH SELENIUM, NUNIT AND .NET” at the .NET User’s group. I just wanted to let you all know the date has changed and I will...
  • 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...
  • 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”.”