stackalloc ifadesi (C# başvurusu)

İfade stackalloc , yığında bir bellek bloğu ayırır. Yöntem yürütüldüğü sırada oluşturulan yığın ayrılmış bellek bloğu, bu yöntem döndürdüğünde otomatik olarak atılır. ile stackallocayrılan belleği açıkça boşaltamazsınız. Yığına ayrılan bellek bloğu çöp toplamaya tabi değildir ve deyimiylefixed sabitlenmesi gerekmez.

Bir stackalloc ifadenin sonucunu aşağıdaki türlerden birine atayabilirsiniz:

  • System.Span<T> veya System.ReadOnlySpan<T>, aşağıdaki örnekte gösterildiği gibi:

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

    Bir veya ReadOnlySpan<T> değişkenine yığın tarafından ayrılan bir bellek bloğu atarken güvenli olmayan bir Span<T> bağlam kullanmanız gerekmez.

    Bu türlerle çalışırken, aşağıdaki örnekte gösterildiği gibi koşullu veya atama ifadelerinde bir stackalloc ifade kullanabilirsiniz:

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

    Aşağıdaki örnekte gösterildiği gibi, bir stackalloc veya ReadOnlySpan<T> değişkenine izin verildiğinde diğer ifadelerin içinde bir Span<T> ifade kullanabilirsiniz:

    Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };
    var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 });
    Console.WriteLine(ind);  // output: 1
    

    Not

    Mümkün olduğunda yığında ayrılan bellekle çalışmak için veya ReadOnlySpan<T> türlerini kullanmanızı Span<T> öneririz.

  • Aşağıdaki örnekte gösterildiği gibi bir işaretçi türü:

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

    Yukarıdaki örnekte gösterildiği gibi, işaretçi türleriyle çalışırken bağlam unsafe kullanmanız gerekir.

    İşaretçi türleri söz konusu olduğunda, değişkeni başlatmak için yalnızca yerel değişken bildiriminde bir stackalloc ifade kullanabilirsiniz.

Yığında kullanılabilir bellek miktarı sınırlıdır. Yığında çok fazla bellek ayırırsanız, bir StackOverflowException oluşturulur. Bunu önlemek için aşağıdaki kuralları izleyin:

  • ile stackallocayırdığınız bellek miktarını sınırlayın. Örneğin, hedeflenen arabellek boyutu belirli bir sınırın altındaysa, belleği yığında ayırırsınız; aksi takdirde, aşağıdaki kodda gösterildiği gibi gerekli uzunlukta bir dizi kullanın:

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

    Not

    Yığında kullanılabilir bellek miktarı kodun yürütüldiği ortama bağlı olduğundan, gerçek sınır değerini tanımlarken muhafazakar olun.

  • İç döngüleri kullanmaktan stackalloc kaçının. Bellek bloğunu döngü dışında ayırın ve döngünün içinde yeniden kullanabilirsiniz.

Yeni ayrılan belleğin içeriği tanımsız. Kullanmadan önce başlatmanız gerekir. Örneğin, tüm öğeleri türündeki Tvarsayılan değere ayarlayan yöntemini kullanabilirsinizSpan<T>.Clear.

Yeni ayrılan belleğin içeriğini tanımlamak için dizi başlatıcı söz dizimini kullanabilirsiniz. Aşağıdaki örnekte bunu yapmanın çeşitli yolları gösterilmektedir:

Span<int> first = stackalloc int[3] { 1, 2, 3 };
Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };

ifadesinde stackalloc T[E], Työnetilmeyen bir tür olmalı ve E negatif olmayan bir int değerine değerlendirilmelidir.

Güvenlik

kullanımı stackalloc , ortak dil çalışma zamanında (CLR) arabellek taşması algılama özelliklerini otomatik olarak etkinleştirir. Arabellek taşması algılanırsa, kötü amaçlı kodun yürütülebilme olasılığını en aza indirmek için işlem mümkün olan en kısa sürede sonlandırılır.

C# dili belirtimi

Daha fazla bilgi için C# dil belirtimininYığın ayırma bölümüne ve İç içe bağlamlarda izin ver stackalloc özellik teklifi notlarına bakın.

Ayrıca bkz.