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.
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 proměnné Span<T> nemusíte používat ReadOnlySpan<T> 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é, doporučujeme používat Span<T> nebo ReadOnlySpan<T> používat typy pro práci s přidělenou pamětí zásobníku.
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.V případě 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á. Abyste tomu předešli, postupujte podle následujících 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í.
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ší bezpečnost ref.
Zabezpečení
Použití automatického stackalloc povolení funkcí detekce přetečení vyrovnávací paměti v modulu CLR (Common Language Runtime). Pokud se zjistí přetečení vyrovnávací paměti, proces se co nejrychleji ukončí, aby se minimalizovala pravděpodobnost, že se spustí škodlivý kód.
specifikace jazyka C#
Další informace najdete v části Přidělení zásobníkuspecifikace jazyka C#.