stackalloc expression (C# reference)
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. You can't explicitly free the memory allocated with stackalloc
. A stack allocated memory block isn't subject to garbage collection and doesn't have to be pinned with a fixed
statement.
You can assign the result of a stackalloc
expression to a variable of one of the following types:
System.Span<T> or System.ReadOnlySpan<T>, as the following example shows:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }
You don't have to use an unsafe context when you assign a stack allocated memory block to a Span<T> or ReadOnlySpan<T> variable.
When you work with those types, you can use a
stackalloc
expression in conditional or assignment expressions, as the following example shows:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
You can use a
stackalloc
expression or a collection expression inside other expressions whenever a Span<T> or ReadOnlySpan<T> variable is allowed, as the following example shows:Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 }); Console.WriteLine(ind); // output: 1 Span<int> numbers2 = [1, 2, 3, 4, 5, 6]; var ind2 = numbers2.IndexOfAny([2, 4, 6, 8]); Console.WriteLine(ind2); // output: 1
Note
We recommend using Span<T> or ReadOnlySpan<T> types to work with stack allocated memory whenever possible.
A pointer type, as the following example shows:
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }
As the preceding example shows, you must use an
unsafe
context when you work with pointer types.In the case of pointer types, you can use a
stackalloc
expression only in a local variable declaration to initialize the variable.
The amount of memory available on the stack is limited. If you allocate too much memory on the stack, a StackOverflowException is thrown. To avoid that, follow the rules below:
Limit the amount of memory you allocate with
stackalloc
. For example, if the intended buffer size is below a certain limit, you allocate the memory on the stack; otherwise, use an array of the required length, as the following code shows:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
Note
Because the amount of memory available on the stack depends on the environment in which the code is executed, be conservative when you define the actual limit value.
Avoid using
stackalloc
inside loops. Allocate the memory block outside a loop and reuse it inside the loop.
The content of the newly allocated memory is undefined. You should initialize it, either with a stackalloc
initializer, or a method like Span<T>.Clear before it's used.
Important
Not initializing memory allocated by stackalloc
is an important difference from the new
operator. Memory allocated using the new
operator is initialized to the 0 bit pattern.
You can use array initializer syntax to define the content of the newly allocated memory. The following example demonstrates various ways to do that:
Span<int> first = stackalloc int[3] { 1, 2, 3 };
Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
// Using collection expressions:
Span<int> fourth = [1, 2, 3];
ReadOnlySpan<int> fifth = [1, 2, 3];
In expression stackalloc T[E]
, T
must be an unmanaged type and E
must evaluate to a non-negative int value. When you use the collection expression syntax to initialize the span, the compiler may use stack allocated storage for a span if it won't violate ref safety.
Security
The use of stackalloc
automatically enables buffer overrun detection features in the common language runtime (CLR). If a buffer overrun is detected, the process is terminated as quickly as possible to minimize the chance that malicious code is executed.
C# language specification
For more information, see the Stack allocation section of the C# language specification and the Permit stackalloc
in nested contexts feature proposal note.