Behind the Code: Stacks and Heaps - Page 1
       by kirupa  |  29 March 2007

All of the tutorials on this site cover high level languages such as C#, ActionScript, PHP, etc. One of the things that make a language a higher-level language is the amount of detail you as a programmer do not have to bother with. Behind the scenes of your cleanly written code, a compiler goes through and does a lot of complicated work.

Most of the time, knowing what the compiler does behind the scenes is not important. But, there will be situations where having a basic idea of what goes on behind your code can either help you to improve your code or debug tricky issues. In this article, I am going to talk about stacks and heaps. Both stacks and heaps play a large role in running your applications.

A program you run contains code that contains bits and pieces of "things" called variables, methods/functions, etc. All of those various bits and pieces are simplified into smaller pieces so that your processor can execute them in some particular order. The exact location where your code is simplified and stored before being further processed and executed can be found in two places: the stack and the heap.

Value and Reference Types
Before delving into the details of stacks and heaps, I must first explain the two types of data you use in .NET - Value and Reference. Value types are often primitives, and as that description implies, store data values in the form of int, double, struct, etc. More specifically, any data type that is based on System.ValueType is a value type. Reference types on the other hand are based on System.Object, and a popular example of a reference type is a Class!

Knowing about value and reference types is important, because that classification determines where in memory they are stored. There are two main regions of memory where programs you run are kept: the stack and the heap. Value types are usually stored on the stack, and reference types are stored on the heap.

Stacks
Let's look at stacks first. A stack is known as LIFO (last-in, first-out) data structure that works similar to you stacking blocks on top of each other and trying to access a random block. For example, take a look at the following diagram with three stages displayed:

 

The most recent block I added is the red one (Stage 1). If I want to access the green block, I need to first remove the red block (Stage 2), and then I need to remove the blue block (Stage 3). This is an example of LIFO where the last block added is the first block to removed - which in our case are the red and blue blocks.

Now, let's expand our understanding of stacks in the computer world by looking at a simple program that calculates a circumference given a radius:

public double getArea(int radius) {
const double PI = 3.14;
double area = PI * radius * radius;
return area;
}

When you run this program, your stack will grow as shown in the following diagram:

 

In Stages 1 and 2, our method and its parameter are put on the stack. In Stage 3, we allocate space for our PI variable, and in Stage 4, we add some space for our area variable. At the end of Step 4, our program has fully executed, and all of the variables that needed to reserve space on the stack have been taken care of. Once you are done executing the code, you clear the stack as shown in Stage 5 and return back to the point in the memory where getArea() once resided!

In practice, your stack also has various pointers that store memory addresses. In the above image, the pink arrows designate a stack pointer that indicates the top of the stack. You also have pointers that tell a subroutine where to return to.

Onwards to the next page!

1 | 2 | 3




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.