stackalloc kifejezés (C# hivatkozás)
Egy stackalloc
kifejezés egy memóriablokkot foglal le a veremen. A metódus végrehajtása során létrehozott halmozott memóriablokkot a rendszer automatikusan elveti, amikor a metódus visszatér. Nem szabadíthatja fel explicit módon a lefoglalt memóriát stackalloc
. A lefoglalt memóriablokkok nem tartoznak szemétgyűjtés hatálya alá, és nem kell utasítással fixed
rögzíteni.
A stackalloc
kifejezés eredményét az alábbi típusok egyikének változóihoz rendelheti:
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 verem által lefoglalt memóriablokkot rendel egy Span<T> vagy ReadOnlySpan<T> változóhoz.
Ha ezekkel a típusokkal dolgozik, használhat kifejezéseket
stackalloc
feltételes vagy hozzárendelési kifejezésekben, ahogyan az alábbi példa is mutatja:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
Más kifejezésekben is használhat kifejezéseket
stackalloc
vagy gyűjteménykifejezéseket, ha engedélyezve van egy Span<T> vagy ReadOnlySpan<T> több változó, ahogy az alábbi példa is mutatja: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: 1
Feljegyzés
Javasoljuk, hogy amikor csak lehetséges, használjon Span<T> vagy ReadOnlySpan<T> használjon típusokat a verem által lefoglalt memória használatához.
Mutatótípus, ahogy az alábbi példa mutatja:
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 csak helyi változódeklarációban használható
stackalloc
kifejezés a változó inicializálásához.
A veremen elérhető memória mennyisége korlátozott. Ha túl sok memóriát foglal le a veremen, a rendszer eldob egy StackOverflowException értéket. Ennek elkerülése érdekében kövesse az alábbi szabályokat:
Korlátozza a lefoglalt
stackalloc
memória mennyiségét. Ha például a puffer tervezett mérete 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 is mutatja:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
Feljegyzé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 hurokban.
Az újonnan lefoglalt memória tartalma nincs meghatározva. Használat előtt inicializálnia kell. Használhatja például azt a Span<T>.Clear metódust, amely az összes elemet az alapértelmezett típusértékre T
állítja.
A tömb inicializáló szintaxisával meghatározhatja az újonnan lefoglalt memória tartalmát. Az alábbi példa ennek különböző módjait mutatja be:
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];
A kifejezésben stackalloc T[E]
nem felügyelt típusnak kell lennie, T
és E
nem negatív int értékre kell kiértékelni. Ha a gyűjteménykifejezés szintaxisát használja a span inicializálásához, a fordító használhatja a verem által lefoglalt tárolót egy spanhoz, ha az nem sérti a ref biztonságát.
Biztonság
Az automatikus használat 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 a rendszer minimalizálja a rosszindulatú kód végrehajtásának esélyét.
C# nyelvspecifikáció
További információkért tekintse meg a C#-nyelv specifikációjának Veremfoglalás szakaszát és az Engedélyezés stackalloc
beágyazott környezetekben funkciójavaslat megjegyzését.
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: