expressão stackalloc (referência C#)stackalloc expression (C# reference)

Uma stackalloc expressão aloca um bloco de memória na pilha.A stackalloc expression allocates a block of memory on the stack. Um bloco de memória alocado na pilha criado durante a execução do método é descartado automaticamente quando esse método é retornado.A stack allocated memory block created during the method execution is automatically discarded when that method returns. Não é possível liberar explicitamente a memória alocada com stackalloc .You cannot explicitly free the memory allocated with stackalloc. Um bloco de memória alocado de pilha não está sujeito à coleta de lixo e não precisa ser fixado com uma fixed instrução.A stack allocated memory block is not subject to garbage collection and doesn't have to be pinned with a fixed statement.

Você pode atribuir o resultado de uma stackalloc expressão a uma variável de um dos seguintes tipos:You can assign the result of a stackalloc expression to a variable of one of the following types:

  • A partir do C# 7,2 System.Span<T> ou System.ReadOnlySpan<T> , como mostra o exemplo a seguir: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;
    }
    

    Você não precisa usar um contexto unsafe quando atribui um bloco de memória alocado na pilha a uma variável Span<T> ou ReadOnlySpan<T>.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.

    Ao trabalhar com esses tipos, você pode usar uma expressão stackalloc em condicional ou expressões de atribuição, como mostra o seguinte exemplo: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];
    

    A partir do C# 8,0, você pode usar uma stackalloc expressão dentro de outras expressões sempre que uma Span<T> ReadOnlySpan<T> variável ou é permitida, como mostra o exemplo a seguir: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
    

    Observação

    É recomendável usar os tipos Span<T> ou ReadOnlySpan<T> sempre que possível para trabalhar com memória alocada na pilha.We recommend using Span<T> or ReadOnlySpan<T> types to work with stack allocated memory whenever possible.

  • Um tipo de ponteiro, como mostra o seguinte exemplo: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;
        }
    }
    

    Como mostra o exemplo anterior, você precisa usar um contexto unsafe ao trabalhar com tipos de ponteiro.As the preceding example shows, you must use an unsafe context when you work with pointer types.

    No caso de tipos de ponteiro, você pode usar uma stackalloc expressão somente em uma declaração de variável local para inicializar a variável.In the case of pointer types, you can use a stackalloc expression only in a local variable declaration to initialize the variable.

A quantidade de memória disponível na pilha é limitada.The amount of memory available on the stack is limited. Se você alocar muita memória na pilha, um StackOverflowException será lançado.If you allocate too much memory on the stack, a StackOverflowException is thrown. Para evitar isso, siga as regras abaixo:To avoid that, follow the rules below:

  • Limite a quantidade de memória que você aloca com 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];
    

    Como a quantidade de memória disponível na pilha depende do ambiente no qual o código é executado, seja conservador quando você define o valor de limite real.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.

  • Evite usar stackalloc loops internos.Avoid using stackalloc inside loops. Aloque o bloco de memória fora de um loop e reutilize-o dentro do loop.Allocate the memory block outside a loop and reuse it inside the loop.

O conteúdo da memória recém-alocada é indefinido.The content of the newly allocated memory is undefined. Você deve inicializá-lo antes do uso.You should initialize it before the use. Por exemplo, você pode usar o Span<T>.Clear método que define todos os itens com o valor padrão do tipo T .For example, you can use the Span<T>.Clear method that sets all the items to the default value of type T.

A partir do C# 7,3, você pode usar a sintaxe do inicializador de matriz para definir o conteúdo da memória alocada recentemente.Beginning with C# 7.3, you can use array initializer syntax to define the content of the newly allocated memory. O seguinte exemplo demonstra várias maneiras de fazer isso: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 };

Em Expression stackalloc T[E] , T deve ser um tipo não gerenciado e E deve ser avaliado como um valor int não negativo.In expression stackalloc T[E], T must be an unmanaged type and E must evaluate to a non-negative int value.

SegurançaSecurity

O uso de stackalloc habilita automaticamente os recursos de detecção de estouro de buffer no CLR (Common Language Runtime).The use of stackalloc automatically enables buffer overrun detection features in the common language runtime (CLR). Se for detectada uma estouro de buffer, o processo será encerrado assim que possível para minimizar a chance de o código mal-intencionado ser executado.If a buffer overrun is detected, the process is terminated as quickly as possible to minimize the chance that malicious code is executed.

Especificação da linguagem C#C# language specification

Para obter mais informações, consulte a seção de alocação de pilha da especificação da linguagem C# e a nota de proposta de recurso permitir stackalloc em contextos aninhados .For more information, see the Stack allocation section of the C# language specification and the Permit stackalloc in nested contexts feature proposal note.

Confira tambémSee also