stackalloc ifadesi (C# başvurusu)

İfade stackalloc , yığında bir bellek bloğu ayırır. Yöntem yürütmesi 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 birfixeddeyimle sabitlenmesi gerekmez.

bir ifadenin stackalloc sonucunu aşağıdaki türlerden birinin değişkenine 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ığınla ayrılmış 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 değişkene izin verildiğinde başka ifadelerin içinde bir Span<T> ifade veya ReadOnlySpan<T> koleksiyon ifadesi 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
    
    Span<int> numbers2 = [1, 2, 3, 4, 5, 6];
    var ind2 = numbers2.IndexOfAny([2, 4, 6, 8]);
    Console.WriteLine(ind2);  // output: 1
    

    Not

    Mümkün olduğunda yığına 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 kurallara uyun:

  • 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, yığının belleğini 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 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ı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 };

// Using collection expressions:
Span<int> fourth = [1, 2, 3];
ReadOnlySpan<int> fifth = [1, 2, 3];

ifadesinde stackalloc T[E], T yönetilmeyen bir tür olmalı ve E negatif olmayan bir int değerine değerlendirilmelidir. Yayılma alanını başlatmak için koleksiyon ifadesi söz dizimini kullandığınızda, derleyici başvuru güvenliğini ihlal etmeyecekse, bir span için yığın ayrılmış depolamayı kullanabilir.

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ülmesi 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 belirtiminin Yığın ayırma bölümüne ve İç içe bağlamlarda izin ver stackalloc özellik teklifi notu'na bakın.

Ayrıca bkz.