C#: Stack & Heap
Published: 2023-06-05 21:42:07

# Background

If you're new to C# which I'm assuming you are, following this series. Let's look at what this actually means, but first we need to understand how C# code works under the hood.

To understand this, we first must dive into memory management used across multiple OOP languages, the Heap and Stack.

## What do these words mean?

The Stack is the part of memory which in essence keeps track of everything that is executed (ran) in our code, and value types.
Whereas the **Heap** is responsible for keep track of our objects and structures (reference types).

In C# there are variables of **Value** type and **Reference** types.

Value types are:

- bool
- byte
- char
- decimal
- double
- enum
- float
- int
- long
- sbyte
- short
- struct
- uint
- ulong
- ushort

Reference types are:

- class
- interface
- delegate
- object
- string

There is another thing involved in this process called _Pointers_. A Pointer is an address for the location in memory for the reference type it belongs to. 

A Pointer (or Reference) and a Reference Type are distinct from one another in that a Pointer is used to retrieve a Reference Type. A pointer is a portion of memory that directs attention to another portion of memory.

Think of it as you have created a  Reference type variable
```csharp
Building house = new Building();
```
Your house,  and a Pointer is your address. The pointer is allocated to the Stack (is your address), and the house reference type is allocated to the Heap. People know how to get to the house, via the Pointer (address).


![showing how values are added to the stack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l44a57a5tswq7v296e02.png)

## The Stack:

Think of it like those child toys you used to play with in doctors surgeries, placing blocks on each spike, but you can't access the bottom block without taking the top ones off first.

The Stack works on a Last In First Out pattern. When a method is called, a new stack frame is created and pushed onto the stack. The stack frame contains space for the method's parameters, return address, local variables, and other relevant information. 

As the method executes, its local variables and parameters are stored within its stack frame.

When we're done with the top box (the method is done executing) we `pop` it off the stack and proceed to use the data in the previous box on the top of the stack.

## The Heap:

The Heap takes care of storing the Reference type variables. 

The heap is more like that pile of shoes you leave at your front door for when you need to grab a pair of shoes but any will do. It's accessible at any time using your pointer because you know exactly where to look.

### Golden Rules:

1. A Reference Type always goes on the Heap

2. Value Types always go on the Stack - Unless, they're declared within a Reference Type, then they go on the Heap.

3. Pointers to the reference type are stored on the Stack. 

4. Global variables will be stored on the Heap as they need to be available to everything. 

The Stack, as we mentioned earlier, is responsible for keeping track of where each thread is during the execution of our code (or what's been executed).

When the code executes a method, the main thread starts executing the instructions, and the code instructions live in the method tables. However, it also puts the method's parameters on the stack too. As the code runs, the variables within the methods are also pushed onto the stack.

Let's see this in an example, it might be easier:

#### Example 1:

```csharp
public int Multiply(int value1, int value2)
{
    int result; // Stack
    result = value1 * value2;
    return result;
}
```

We call the `Multiply` method, and as soon as we do, the method's parameters are pushed onto the stack (the method itself does not live on the stack). So currently stack would look something like this:

```console
value2 | int
value1 | int
```

The thread executes the code's instructions, and as it runs through the code, it sees the `result` variable. As we know local Value type variables are pushed onto the stack.

```console 
result | int
value2 | int
value1 | int
```

The method finishes executing and returns the `result` variable, thus popping it off the stack. 

All memory allocated on the stack is cleaned up. 

In this example, our `result` variable is placed on the stack. As a matter of fact, every time a Value Type is declared within the body of a method or parameters it will end up on the Stack.


#### Example 2:

```csharp

public void Main(string[] args){
  private int number = 0;
  Application app = new Application();
}

public class Application  {
  private int number = 42;
}
```

Application Class = Reference Type

Ok, so looking at the example above where do you think the variables will be allocated to ?

Let's di-sect:

`number` is a local Value type variable within our program meaning it will be allocated to the Stack. 

The `app` variable of Reference type , so it will be be allocated to the Heap and a Pointer will be allocated to the Stack to get to it. Stack. 

Here's a tricky one, where will the `private int number` be assigned to ?

The Heap too ! As its a top level property within a Reference Type.

Let's add something a little more complex, to get the cogs working. 

What about the below example:

``` csharp
public void Main(string[] args){
  private int number = 0;
  
  Application app = new Application();
  app.SomeMethod(420);
}

public class Application  {
  private int number = 42;

  public void SomeMethod(int number){
     
  }
}
```
Ok, so where would we expect the `number` argument to be assigned when the `SomeMethod` method is called?


Well this is where people often get confused. Yes it is inside a Reference type, however it is a method parameter so therefore goes on the Stack! As we know all method parameters of Value type and local method variables are assigned to the Stack. 



**Important Note:**
When using Reference types, the actual variables are referring to the Pointer to the type, not each object itself.

Wait, what do I mean ? Let's take a look:

**Example:**

```csharp

public class Application
{
    public int NumberOfThreads { get; set; }
}

public void Main (string[] args){
  Application app1 = new Application();
  Application app2 = new Application();

  app1.NumberOfThread = 10;
  Console.WriteLine(app1.NumberOfThreads) // 10

  app2 = app1;
  app2.NumberOfThreads = 40;


  Console.WriteLine(app1.NumberOfThreads); //40
}
```

What ? Why has `app1` Number of Threads changed, we haven't updated it. 

Well when we assigned app2 to app1, it does this by Reference. It adds a pointer to the same reference type on the heap as the 1st pointer.

Therefore, when we updated the value of `NumberOfThreads` on `app2` , we're updating the now shared reference, meaning `app1` and `app2` values are the same value, see image below to try and help:


![Showing Stack & Heap changes with reference allocation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhuslvu9mpb53jd5pk4e.png)


It can be a tough concept to grasp, but hopefully it makes sense, as it will lead on nicely to my next topic "By ref vs By value" method parameters.

As always, leave a comment if you would like anything else explained, and don't forget to subscribe, or give me a follow on [twitter](https://twitter.com/gweaths) for updates on new content. :+