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 door stackalloc. Een stack-toegewezen geheugenblok is niet onderhevig aan garbagecollection en hoeft niet te worden vastgemaakt door een fixed instructie.

De C#-taalreferentiedocumenten beschrijven de meest recent uitgebrachte versie van de C#-taal. Het bevat ook de eerste documentatie voor functies in openbare previews voor de aanstaande taalrelease.

De documentatie identificeert alle functies die voor het eerst zijn geïntroduceerd in de laatste drie versies van de taal of in de huidige openbare previews.

Aanbeveling

Raadpleeg het artikel over de versiegeschiedenis van de C#-taal om te achterhalen wanneer een functie voor het eerst is geïntroduceerd in C#.

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 aan stack toegewezen geheugenblok toewijst aan een Span<T> of ReadOnlySpan<T> variabele.

    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

    Gebruik Span<T> of ReadOnlySpan<T> typen om waar mogelijk te werken met aan stack toegewezen geheugen.

  • 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;
        }
    }
    

    U moet een unsafe context gebruiken wanneer u met aanwijzertypen werkt.

    Notitie

    Met de preview-functie voor geheugenveiligheid die beschikbaar is in C# 15, kunt u een stackalloc expressie converteren naar een aanwijzer buiten een unsafe context. Bewerkingen die toegang hebben tot het toegewezen geheugen via de aanwijzer, vereisen nog steeds een unsafe context.

    Voor aanwijzertypen kunt u een stackalloc expressie alleen gebruiken in een lokale variabeledeclaratie 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 deze regels om deze uitzondering te voorkomen:

  • Beperk de hoeveelheid geheugen die u toewijst met behulp van 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. U moet deze initialiseren voordat deze wordt gebruikt, hetzij met een stackalloc initialisatiefunctie of een methode zoals Span<T>.Clear.

Belangrijk

Het niet initialiseren van het toegewezen geheugen stackalloc is een belangrijk verschil met de new operator. Geheugen toegewezen met behulp van de new operator wordt geïnitialiseerd op het 0-bits patroon.

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

Als stackalloc u bufferoverschrijdingsdetectiefuncties automatisch inschakelt in de Common Language Runtime (CLR). Als de runtime een bufferoverschrijding detecteert, wordt het proces zo snel mogelijk beëindigd om de kans te verminderen dat schadelijke code wordt uitgevoerd.

C#-taalspecificatie

Zie de sectie Stack-toewijzing van de C#-taalspecificatievoor meer informatie.

Zie ook