stackalloc 식(C# 참조)stackalloc expression (C# reference)

stackalloc 식은 스택에 메모리 블록을 할당합니다.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. stackalloc을 사용하여 할당된 메모리를 명시적으로 해제할 수 없습니다.You cannot explicitly free the memory allocated with stackalloc. 스택 할당 메모리 블록에는 가비지 수집이 적용되지 않으며, fixed을 사용해서 고정하지 않아도 됩니다.A stack allocated memory block is not subject to garbage collection and doesn't have to be pinned with a fixed statement.

stackalloc 식의 결과를 다음 형식 중 하나의 변수에 할당할 수 있습니다.You can assign the result of a stackalloc expression to a variable of one of the following types:

  • C# 7.2부터 System.Span<T> 또는 System.ReadOnlySpan<T>(다음 예제 참조):Beginning with C# 7.2, 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;
    }
    

    Span<T> 또는 ReadOnlySpan<T> 변수에 스택 할당 메모리 블록을 할당할 때 unsafe 컨텍스트를 사용하지 않아도 됩니다.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.

    이러한 형식으로 작업하는 경우 다음 예제와 같이 조건식 또는 대입식에 stackalloc 식을 사용할 수 있습니다.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];
    

    C# 8.0부터 다음 예제와 같이 Span<T> 또는 ReadOnlySpan<T> 변수가 허용되는 경우 다른 식 내부에서 stackalloc 식을 사용할 수 있습니다.Beginning with C# 8.0, you can use a stackalloc 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<T> 또는 ReadOnlySpan<T> 형식을 사용하는 것이 좋습니다.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;
        }
    }
    

    포인터 형식으로 작업할 때는 위 예제와 같이 unsafe 컨텍스트를 사용해야 합니다.As the preceding example shows, you must use an unsafe context when you work with pointer types.

    포인터 형식의 경우 지역 변수 선언에서만 stackalloc 식을 사용하여 변수를 초기화할 수 있습니다.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. 스택에 너무 많은 메모리를 할당하는 경우 StackOverflowException이 throw됩니다.If you allocate too much memory on the stack, a StackOverflowException is thrown. 이를 방지하려면 다음 규칙을 따르세요.To avoid that, follow the rules below:

  • stackalloc을 사용하여 할당하는 메모리의 양을 제한합니다.Limit the amount of memory you allocate with stackalloc:

    const int MaxStackLimit = 1024;
    Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[inputLength] : new byte[inputLength];
    

    스택에서 사용 가능한 메모리 양은 코드를 실행하는 환경에 따라 달라지므로 실제 제한 값을 정의할 때는 신중해야 합니다.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.

  • 루프 내부에서 stackalloc을 사용하지 마세요.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 before the use. 예를 들어 모든 항목을 T형식의 기본값으로 설정하는 Span<T>.Clear 메서드를 사용할 수 있습니다.For example, you can use the Span<T>.Clear method that sets all the items to the default value of type T.

C# 7.3부터, 배열 이니셜라이저 구문을 사용하여 새로 할당된 메모리의 콘텐츠를 정의할 수 있습니다.Beginning with C# 7.3, 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 };

stackalloc T[E]에서 T관리되지 않는 형식이어야 하며 E는 음수가 아닌 int 값으로 계산되어야 합니다.In expression stackalloc T[E], T must be an unmanaged type and E must evaluate to a non-negative int value.

보안Security

stackalloc를 사용하면 CLR(공용 언어 런타임)에서 버퍼 오버런 검색 기능이 자동으로 사용됩니다.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# 언어 사양C# language specification

자세한 내용은 C# 언어 사양스택 할당 섹션과 중첩 컨텍스트 기능 제안 노트의 stackalloc 허용을 참조하세요.For more information, see the Stack allocation section of the C# language specification and the Permit stackalloc in nested contexts feature proposal note.

참고 항목See also