Delen via


stackalloc-expressie (C#-verwijzing)

Een stackalloc expressie wijst een blok geheugen toe aan de stack. Een stack-toegewezen geheugenblok dat is gemaakt tijdens de uitvoering van de methode, wordt automatisch verwijderd wanneer deze methode wordt geretourneerd. U kunt het toegewezen geheugen niet expliciet vrij maken.stackalloc Een aan een stack toegewezen geheugenblok is niet onderhevig aan garbagecollection en hoeft niet te worden vastgemaakt aan een fixed instructie.

U kunt het resultaat van een stackalloc expressie toewijzen aan een variabele van een van de volgende typen:

  • System.Span<T> of System.ReadOnlySpan<T>, zoals in het volgende voorbeeld wordt weergegeven:

    int length = 3;
    Span<int> numbers = stackalloc int[length];
    for (var i = 0; i < length; i++)
    {
        numbers[i] = i;
    }
    

    U hoeft geen onveilige context te gebruiken wanneer u een toegewezen stackgeheugenblok aan een Span<T> of ReadOnlySpan<T> variabele toewijst.

    Wanneer u met deze typen werkt, kunt u een stackalloc expressie gebruiken in voorwaardelijke expressies of toewijzingsexpressies, zoals in het volgende voorbeeld wordt weergegeven:

    int length = 1000;
    Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
    

    U kunt een stackalloc expressie of een verzamelingsexpressie in andere expressies gebruiken wanneer een Span<T> of ReadOnlySpan<T> variabele is toegestaan, zoals in het volgende voorbeeld wordt weergegeven:

    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
    

    Notitie

    We raden u aan Span<T> om waar mogelijk te werken met toegewezen stackgeheugen of ReadOnlySpan<T> typen.

  • Een aanwijzertype, zoals in het volgende voorbeeld wordt weergegeven:

    unsafe
    {
        int length = 3;
        int* numbers = stackalloc int[length];
        for (var i = 0; i < length; i++)
        {
            numbers[i] = i;
        }
    }
    

    Zoals in het voorgaande voorbeeld wordt weergegeven, moet u een unsafe context gebruiken wanneer u met aanwijzertypen werkt.

    In het geval van aanwijzertypen kunt u een stackalloc expressie alleen gebruiken in een declaratie van een lokale variabele om de variabele te initialiseren.

De hoeveelheid geheugen die beschikbaar is op de stack is beperkt. Als u te veel geheugen aan de stack toewijst, wordt er een StackOverflowException gegenereerd. Volg de onderstaande regels om dit te voorkomen:

  • Beperk de hoeveelheid geheugen die u toewijst.stackalloc Als de beoogde buffergrootte bijvoorbeeld onder een bepaalde limiet ligt, wijst u het geheugen toe aan de stack; gebruik anders een matrix van de vereiste lengte, zoals in de volgende code wordt weergegeven:

    const int MaxStackLimit = 1024;
    Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
    

    Notitie

    Omdat de hoeveelheid geheugen die beschikbaar is voor de stack, afhankelijk is van de omgeving waarin de code wordt uitgevoerd, moet u conservatief zijn wanneer u de werkelijke limietwaarde definieert.

  • Vermijd het gebruik van stackalloc binnenlussen. Wijs het geheugenblok buiten een lus toe en gebruik het opnieuw binnen de lus.

De inhoud van het nieuw toegewezen geheugen is niet gedefinieerd. Initialiseer deze vóór het gebruik. U kunt bijvoorbeeld de Span<T>.Clear methode gebruiken waarmee alle items worden ingesteld op de standaardwaarde van het type T.

U kunt de syntaxis van de matrix-initialisatiefunctie gebruiken om de inhoud van het zojuist toegewezen geheugen te definiëren. In het volgende voorbeeld ziet u verschillende manieren om dit te doen:

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];

In expressie stackalloc T[E]T moet een onbeheerd type zijn en E moet deze resulteren in een niet-negatieve intwaarde. Wanneer u de syntaxis van de verzamelingsexpressie gebruikt om de spanwijdte te initialiseren, kan de compiler stack-toegewezen opslag voor een periode gebruiken als deze niet in strijd is met de veiligheid van verw.

Beveiliging

stackalloc Door automatisch bufferdetectiefuncties in te schakelen in de COMMON Language Runtime (CLR). Als er een bufferoverschrijding wordt gedetecteerd, wordt het proces zo snel mogelijk beëindigd om de kans te minimaliseren dat schadelijke code wordt uitgevoerd.

C#-taalspecificatie

Zie voor meer informatie de sectie Stack-toewijzing van de C#-taalspecificatie en de vergunning stackalloc in geneste contexten functievoorstelnotitie.

Zie ook