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)
{
// ...
}