Skip to content

stackalloc

The following chapter will show some tips and tricks around the stackalloc and its usage.

A stackalloc expression allocates a block of memory on the stack. A stack allocated memory block created during the method execution is automatically discarded when that method returns. Taken from here

Allocate only small amounts of memory

The stack has a limited size and attempting to allocate a hugerelatively speaking amount of memory and if taken too much a StackOverflowException is thrown which is not recoverable. Linux might have a big stack size but embedded devices can limit the size to the kilobyte range.

Bad Allocate a huge amount.

Span<byte> = stackalloc byte[1024 * 1024];

Also be careful if taken user input which can crash the program:

Span<byte> = stackalloc byte[userInput];

Good Take small amounts of memory.

Span<byte> = stackalloc byte[1024];

Good Fallback to traditional heap allocation if over a specific threshold.

Span<byte> = userInput <= 1024 ? stackalloc byte[1024] : new byte[userInput];

stackalloc is not zero initialized

In contrast to arrays allocated via new stackalloc does not zero initialize arrays. Especially if one in the caller chain uses the SkipLocalsInitAttribute.

Bad Don’t relay on zero initialized arrays.

Span<int> buffer = stackalloc int[3];
buffer[0] = 1;
buffer[1] = 1;

int result = buffer[0] + buffer[1] + buffer[2]; // Is not necessarily 2

Good Call Clear or Fill to initialize the array if needed.

Span<int> buffer = stackalloc int[3];
buffer.Clear(); // or buffer.Fill(0);
buffer[0] = 1;
buffer[1] = 1;

int result = buffer[0] + buffer[1] + buffer[2]; // Is 2

stackalloc in a loop

Every stackalloc gets only deallocated after the function terminates. That means in a loop multiple stackalloc will pill up memory which ultimately can lead to an StackOverflowException. Furthermore it is inefficient to allocate always the same amount of memory.

Bad Allocating over and over again the “same” memory inside a loop pilling up stack memory.

for (int i = 0; i < 1000; ++i)
{
    Span<char> buffer = stackalloc char[256];
    // ...
}

Good Create one slice of memory outside the loop.

Span<char> buffer = stackalloc char[256];
for (int i = 0; i < 1000; ++i)
{   
    // ...
}