stackalloc kifejezés (C#-referencia)
Egy stackalloc
kifejezés memóriablokkot foglal le a veremen. A metódus végrehajtása során létrehozott, lefoglalt memóriablokkokat a rendszer automatikusan elveti, amikor a metódus visszatér. A használatával lefoglalt stackalloc
memória nem szabadítható fel explicit módon. A lefoglalt memóriablokkok nem tartoznak szemétgyűjtés hatálya alá, és nem kell utasítássalfixed
rögzíteni.
A stackalloc
kifejezések eredményét az alábbi típusok egyikének változóihoz rendelheti hozzá:
System.Span<T> vagy System.ReadOnlySpan<T>, ahogy az alábbi példa mutatja:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }
Nem kell nem biztonságos környezetet használnia, ha egy veremhez lefoglalt memóriablokkot rendel egy Span<T> vagy ReadOnlySpan<T> változóhoz.
Ha ezekkel a típusokkal dolgozik, használhat egy
stackalloc
kifejezést feltételes vagy hozzárendelési kifejezésekben, ahogy az alábbi példa mutatja:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
Ha egy vagy ReadOnlySpan<T> változó engedélyezve van, más kifejezésekben is használhat
stackalloc
kifejezéseketSpan<T>, ahogy az alábbi példában látható:Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 }); Console.WriteLine(ind); // output: 1
Megjegyzés
Javasoljuk, hogy Span<T> használja a vagy ReadOnlySpan<T> típusokat a lefoglalt memória veremhez való használatához, amikor csak lehetséges.
A mutató típusa, ahogy az alábbi példában látható:
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }
Ahogy az előző példában is látható, a mutatótípusok használatakor kontextust
unsafe
kell használnia.Mutatótípusok esetén a változó inicializálásához csak helyi változódeklarációban használható
stackalloc
kifejezés.
A veremen rendelkezésre álló memória mennyisége korlátozott. Ha túl sok memóriát foglal le a veremen, StackOverflowException egy lesz eldobva. Ennek elkerülése érdekében kövesse az alábbi szabályokat:
Korlátozza a(z) használatával
stackalloc
lefoglalt memória mennyiségét. Ha például a kívánt pufferméret egy bizonyos korlát alatt van, lefoglalja a memóriát a veremen; ellenkező esetben használjon egy tömböt a szükséges hosszból, ahogy az alábbi kód mutatja:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
Megjegyzés
Mivel a veremen rendelkezésre álló memória mennyisége a kód végrehajtásának környezetétől függ, a tényleges korlátérték meghatározásakor legyen konzervatív.
Kerülje a belső hurkok használatát
stackalloc
. Foglalja le a memóriablokkot egy hurokon kívül, és használja újra a hurokon belül.
Az újonnan lefoglalt memória tartalma nincs meghatározva. Használat előtt inicializálja. Használhatja például azt a Span<T>.Clear metódust, amely az összes elemet a típus T
alapértelmezett értékére állítja.
A tömb inicializáló szintaxisával meghatározhatja az újonnan lefoglalt memória tartalmát. Az alábbi példa ezt többféleképpen szemlélteti:
Span<int> first = stackalloc int[3] { 1, 2, 3 };
Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
A kifejezésben stackalloc T[E]
T
nem felügyelt típusnak kell lennie, és E
nem negatív int értékre kell kiértékelnie.
Biztonság
Az automatikusan lehetővé teszi a stackalloc
puffertúlcsordulás-észlelési funkciókat a közös nyelvi futtatókörnyezetben (CLR). Ha puffertúlcsordulást észlel, a folyamat a lehető leggyorsabban leáll, hogy minimalizálja a rosszindulatú kód végrehajtásának esélyét.
C#-nyelv specifikációja
További információ: A C# nyelv specifikációjánakStack allocation (Veremfoglalás) szakasza és az Engedélyezés stackalloc
beágyazott környezetekben funkciójavaslat megjegyzése.