Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A expressão stackalloc aloca um bloco de memória na pilha. Um bloco de memória alocado na pilha criado durante a execução do método é descartado automaticamente quando esse método é retornado. Você não pode liberar explicitamente a memória alocada com stackalloc. Um bloco de memória alocado por pilha não está sujeito a Coleta de lixo e não precisa ser fixado com uma fixed instrução.
A linguagem C# faz referência a documentos da versão mais recentemente lançada da linguagem C#. Ele também contém a documentação inicial para funcionalidades em pré-visualizações públicas para o próximo lançamento do idioma.
A documentação identifica qualquer recurso introduzido pela primeira vez nas três últimas versões do idioma ou nas versões prévias públicas atuais.
Dica
Para descobrir quando um recurso foi introduzido pela primeira vez em C#, consulte o artigo sobre o histórico de versão da linguagem C#.
Você pode atribuir o resultado de uma expressão stackalloc a uma variável de um dos seguintes tipos:
System.Span<T> ou System.ReadOnlySpan<T> como mostrado no exemplo a seguir:
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 não seguro ao atribuir um bloco de memória alocado por pilha a um Span<T> ou ReadOnlySpan<T> variável.
Ao trabalhar com esses tipos, você pode usar uma expressão
stackallocem condicional ou expressões de atribuição, como mostra o seguinte exemplo:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];Você pode usar uma expressão
stackallocou uma expressão de coleção dentro de outras expressões sempre que uma variável Span<T> ou ReadOnlySpan<T> for permitida, como mostra o exemplo a seguir: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: 1Observação
Use Span<T> ou ReadOnlySpan<T> tipos para trabalhar com memória alocada em pilha sempre que possível.
Um tipo de ponteiro, como mostra o seguinte exemplo:
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
unsafeao trabalhar com tipos de ponteiro.Para tipos de ponteiro, você pode usar uma
stackallocexpressão somente em uma declaração de variável local para inicializar a variável.
A quantidade de memória disponível na pilha é limitada. Se você alocar muita memória na pilha, um StackOverflowException será lançado. Para evitar essa exceção, siga estas regras:
Limite a quantidade de memória alocada com
stackalloc. Por exemplo, se o tamanho do buffer pretendido estiver abaixo de um determinado limite, você alocará a memória na pilha; caso contrário, use uma matriz do comprimento necessário, como mostra o seguinte código:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];Observação
Como a quantidade de memória disponível na pilha depende do ambiente em que o código é executado, seja conservador quando você definir o valor do limite real.
Evite usar
stackallocdentro de loops. Aloque o bloco de memória fora de um loop e reutilize-o dentro do loop.
O conteúdo da memória recém-alocada é indefinido. Você deve inicializá-lo, seja com um stackalloc inicializador ou um método como Span<T>.Clear antes de ser usado.
Importante
Não inicializar a memória alocada por stackalloc é uma diferença importante do new operador. A memória alocada usando o new operador é inicializada para o padrão de 0 bits.
Você pode usar a sintaxe do inicializador de matriz para definir o conteúdo da memória recém-alocada. O seguinte exemplo demonstra várias maneiras de fazer isso:
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];
Na expressão stackalloc T[E], T deve ser um tipo não gerenciado e E deve ser avaliado como um valor int não negativo. Quando você usa a sintaxe de expressão de coleção para inicializar o intervalo, o compilador pode usar o armazenamento alocado de pilha para um intervalo se ele não violar a segurança de ref.
Segurança
O uso stackalloc ativa automaticamente os recursos de detecção de sobrecarga de buffer no CLR (Common Language Runtime). Se o runtime detectar uma sobrecarga de buffer, ele encerrará o processo o mais rápido possível para reduzir a chance de que o código mal-intencionado seja executado.
Especificação da linguagem C#
Para obter mais informações, consulte a seção Alocação de pilha da especificação da linguagem C#.