Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Uma stackalloc expressão aloca um bloco de memória na pilha. Um bloco de memória alocado por pilha criado durante a execução do método é automaticamente descartado quando esse método retorna. Não é possível liberar explicitamente a memória alocada com stackalloco . Um bloco de memória alocado por pilha não está sujeito à coleta de lixo e não precisa ser fixado com uma fixed instrução.
A referência da linguagem C# documenta a versão mais recentemente lançada da linguagem C#. Contém também documentação inicial para funcionalidades em versões preliminares públicas para a próxima versão da linguagem.
A documentação identifica qualquer funcionalidade introduzida pela primeira vez nas últimas três versões da língua ou em pré-visualizações públicas atuais.
Sugestão
Para saber quando uma funcionalidade foi introduzida pela primeira vez em C#, consulte o artigo sobre o histórico de versões da linguagem C#.
Você pode atribuir o resultado de uma stackalloc expressão a uma variável de um dos seguintes tipos:
System.Span<T> ou System.ReadOnlySpan<T>, como mostra o exemplo a seguir:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }Não precisas de usar um contexto inseguro quando atribuis um bloco de memória alocado pela pilha a uma Span<T> variável ou.ReadOnlySpan<T>
Ao trabalhar com esses tipos, você pode usar uma
stackallocexpressão em expressões condicionais ou de atribuição, como mostra o exemplo a seguir:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];Você pode usar uma
stackallocexpressão ou uma expressão de coleção dentro de outras expressões sempre que uma Span<T>ReadOnlySpan<T> ou variável 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: 1Nota
Use Span<T> ou ReadOnlySpan<T> tipos para trabalhar com a memória alocada à pilha sempre que possível.
Um tipo de ponteiro, como mostra o exemplo a seguir:
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ê deve usar um
unsafecontexto ao trabalhar com tipos de ponteiro.Para tipos de ponteiros, pode usar uma
stackallocexpressão apenas numa declaração local de variável 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 é lançado. Para evitar essa exceção, siga estas regras:
Limite a quantidade de memória alocada com
stackalloco . 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 código a seguir:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];Nota
Como a quantidade de memória disponível na pilha depende do ambiente em que o código corre, seja conservador ao definir o valor limite real.
Evite usar
stackallocloops internos. 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 no padrão de bits 0.
Você pode usar a sintaxe do inicializador de matriz para definir o conteúdo da memória recém-alocada. O exemplo a seguir 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 avaliar para um valor int não negativo. Quando usas a sintaxe da expressão de coleção para inicializar o span, o compilador pode usar armazenamento alocado pela pilha para um span se não violar a segurança da referência.
Segurança
O uso stackalloc automático ativa as funcionalidades de deteção de overrun de buffer no tempo de execução da common language (CLR). Se o runtime detetar um overrun do buffer, termina o processo o mais rapidamente possível para reduzir a probabilidade de código malicioso ser 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#.