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 fixedrö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 stackallocmemó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