stackalloc expression
stackalloc
Expressions on the stack(stack
) allocate memory blocks on.
Blocks of memory allocated in the stack created during method execution are automatically discarded when the method returns. Cannot be explicitly releasedstackalloc
Allocated memory.stackalloc
The allocated memory blocks are not affected by garbage collection and do not have to passfixed
The statement is fixed.
Stack memory, stack memory development is fast and efficient, but limited resources, usually limited to 1M.
Canstackalloc
The result of an expression is assigned to variables of any of the following types:
stackalloc assigns the <T> or <T> type
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }
Willstack allocates memory blocks
Assign to<T>
or<T>
Variables of types do not have to use unsafe contexts (unsafe context
)。
Can be used anywhere the expression allowsstackalloc
, and if neededAllocate memory
When it is recommended to use it as much as possibleSpan<T>
orReadOnlySpan<T>
type.
int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = (stackalloc[] { 2, 4, 6, 8 }); (ind); // output: 1
stackalloc allocation pointer type
The following example, for pointer type,stackalloc
Expressions can only be used in the initialization of local variable declarations.
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }
Using pointer type, an unsafe context must be used (unsafe context
)。
Notes on stackalloc allocation memory
The amount of memory available on the stack is limited, which can happen if too much memory is allocated*Exception
abnormal. Therefore, the following points need to be paid attention to:
- Restricted use
stackalloc
The amount of memory allocated.
For example, if the expected buffer size is below a certain limit, you can allocate memory on the stack; otherwise, use an array of required length. The following code looks like:
const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
The amount of memory available on the stack depends on the execution environment of the code.
- Avoid using it inside a loop
stackalloc
. Outside the loopallocate
Allocate memory blocks and reuse them inside the loop.
The contents of the newly allocated memory are undefined. Must be initialized before use. For example, you can useSpan<T>.Clear
Method sets all element items to typeT
The default value of .
The contents of newly allocated memory can also be defined using an array initializer.
Span<int> first = stackalloc int[3] { 1, 2, 3 }; Span<int> second = stackalloc int[] { 1, 2, 3 }; ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
Unmanaged type
Defining pointers,stackalloc T[n]
When , its type can only be an unmanaged type. (Although unmanaged types are almost indistinguishable from primitive types in C# in terms of use and form, you can still understand it).
The following types are or are also unmanaged:
-
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
, orbool
- any
enum
type - any
pointer
type - Any user-defined that contains only unmanaged type fields (
user-defined
)ofstruct
type
Using unmanaged generic constraintsunmanaged
, specify a non-managed type whose type parameter is a non-pointer and cannot be nulled.
Construct type containing only unmanaged type fields (constructed struct type
) is also unmanaged. As shown in the following example,DisplaySize<T>()
The generic constraints of the method areunmanaged
, when calledCoords<int>
、Coords<double>
Use as an unmanaged type:
using System; public struct Coords<T> { public T X; public T Y; } public class UnmanagedTypes { public static void Main() { DisplaySize<Coords<int>>(); DisplaySize<Coords<double>>(); } private unsafe static void DisplaySize<T>() where T : unmanaged { ($"{typeof(T)} is unmanaged and its size is {sizeof(T)} bytes"); } } // Output: // Coords`1[System.Int32] is unmanaged and its size is 8 bytes // Coords`1[] is unmanaged and its size is 16 bytes
Generic StructureCoords<T>
Can be of unmanaged and managed construct types. Of course, it can also be limited to unmanaged types, as follows:
public struct Coords<T> where T : unmanaged { public T X; public T Y; }
refer to
stackalloc expression
Unmanaged types
The above is the detailed explanation of C#’s use of stackalloc to allocate stack memory and unmanaged types. For more information about C#’s stackalloc allocating stack memory, please pay attention to my other related articles!