stackalloc ifadesi (C# başvurusu)

İfade stackalloc yığında bir bellek bloğu ayırır. Yöntem yürütme sırasında 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 bir fixed deyimle sabitlenmesi gerekmez.

bir ifadenin stackalloc sonucunu aşağıdaki türlerden birine sahip bir değişkene atayabilirsiniz:

  • Aşağıdaki örnekte gösterildiği gibi C# 7.2 System.Span<T> veya System.ReadOnlySpan<T>ile başlayarak:

    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 ayrılmış 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];
    

    C# 8.0 sürümünden başlayarak, 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 stackalloc başlatmak için yalnızca yerel değişken bildiriminde bir 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 koruyucu olun.

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

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

C# 7.3 sürümünden başlayarak, 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ğeri olarak 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ülme 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.