Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Výraz stackalloc přidělí blok paměti v zásobníku. Blok paměti přidělený zásobníkem vytvořený během provádění metody se automaticky zahodí při vrácení této metody. Nemůžete explicitně uvolnit paměť přidělenou stackalloc. Blok paměti přidělený zásobníkem není předmětem uvolňování paměti a nemusí být připnut pomocí fixed příkazu.
Referenční dokumentace jazyka C# dokumentuje naposledy vydané verze jazyka C#. Obsahuje také počáteční dokumentaci k funkcím ve verzi Public Preview pro nadcházející jazykovou verzi.
Dokumentace identifikuje všechny funkce, které byly poprvé představeny v posledních třech verzích jazyka nebo v aktuálních verzích Public Preview.
Návod
Informace o tom, kdy byla funkce poprvé představena v jazyce C#, najdete v článku o historii verzí jazyka C#.
Výsledek výrazu stackalloc můžete přiřadit proměnné jednoho z následujících typů:
System.Span<T> nebo System.ReadOnlySpan<T>, jak ukazuje následující příklad:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }Při přiřazování přiděleného bloku paměti zásobníku k Span<T> proměnné ReadOnlySpan<T> nemusíte používat nebezpečný kontext.
Při práci s těmito typy můžete výraz použít
stackallocve výrazech podmíněného nebo přiřazení, jak ukazuje následující příklad:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];Výraz nebo výraz kolekce můžete použít
stackallocv jiných výrazech vždy, když Span<T> je povolená proměnná ReadOnlySpan<T> , jak ukazuje následující příklad: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: 1Poznámka:
Pokud je to možné, použijte Span<T> nebo ReadOnlySpan<T> typy pro práci se zásobníkem přidělenou pamětí.
Typ ukazatele, jak ukazuje následující příklad:
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }Jak ukazuje předchozí příklad, musíte při práci s typy ukazatelů použít
unsafekontext.U typů ukazatelů můžete k inicializaci proměnné použít
stackallocvýraz pouze v deklaraci místní proměnné.
Množství paměti dostupné v zásobníku je omezené. Pokud v zásobníku přidělíte příliš mnoho paměti, vyvolá StackOverflowException se vyvolá. Pokud se chcete této výjimce vyhnout, postupujte podle těchto pravidel:
Omezte množství paměti, kterou přidělíte .
stackallocPokud je například zamýšlená velikost vyrovnávací paměti nižší než určitý limit, přidělíte paměť v zásobníku; jinak použijte pole požadované délky, jak ukazuje následující kód:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];Poznámka:
Vzhledem k tomu, že množství paměti dostupné v zásobníku závisí na prostředí, ve kterém se kód spouští, buďte při definování skutečné mezní hodnoty konzervativnější.
Vyhněte se používání
stackallocvnitřních smyček. Přidělte blok paměti mimo smyčku a znovu ho použijte uvnitř smyčky.
Obsah nově přidělené paměti není definován. Měli byste ho inicializovat buď pomocí inicializátoru stackalloc , nebo metody, jako Span<T>.Clear je předtím, než se použije.
Důležité
Inicializace paměti přidělená operátorem stackalloc je důležitým rozdílem od operátoru new . Paměť přidělená pomocí operátoru new se inicializuje na 0bitový vzor.
Pomocí syntaxe inicializátoru pole můžete definovat obsah nově přidělené paměti. Následující příklad ukazuje různé způsoby, jak to provést:
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];
Ve výrazu stackalloc T[E]Tmusí být nespravovaný typ a E musí být vyhodnocen jako nezáporná hodnota int. Pokud k inicializaci rozsahu použijete syntaxi výrazu kolekce , může kompilátor použít úložiště přidělené zásobníkem pro rozsah, pokud neporušuje bezpečnost ref.
Zabezpečení
Použití stackalloc automatického zapnutí funkcí detekce přetečení vyrovnávací paměti v modulu CLR (Common Language Runtime). Pokud modul runtime zjistí přetečení vyrovnávací paměti, ukončí proces co nejrychleji, aby se snížila pravděpodobnost spuštění škodlivého kódu.
specifikace jazyka C#
Další informace najdete v části Přidělení zásobníkuspecifikace jazyka C#.