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. tarafından stackallocayrılan belleği açıkça boşaltamazsınız. Yığına ayrılmış bellek bloğu çöp toplamaya tabi değildir ve bir fixed deyimle sabitlenmesi gerekmez.

C# dili başvuru belgesi, C# dilinin en son yayımlanan sürümünü gösterir. Ayrıca, yaklaşan dil sürümü için genel önizlemelerdeki özelliklere yönelik ilk belgeleri içerir.

Belgelerde ilk olarak dilin son üç sürümünde veya geçerli genel önizlemelerde sunulan tüm özellikler tanımlanır.

Tavsiye

Bir özelliğin C# dilinde ilk tanıtıldığı zamanları bulmak için C# dil sürümü geçmişi makalesine bakın.

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şullustackallocbir 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 kullanınSpan<T>.

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

    İşaretçi türleriyle çalışırken bağlam unsafe kullanmanız gerekir.

    Not

    C# 15'te bulunan bellek güvenliği önizleme özelliği, bir stackalloc ifadeyi bağlamın dışındaki unsafe bir işaretçiye dönüştürmenizi sağlar. İşaretçi aracılığıyla ayrılan belleğe erişen işlemler yine de bir unsafe bağlam gerektirir.

    İşaretçi türleri için, bir stackalloc ifadeyi yalnızca yerel değişken bildiriminde kullanarak değişkeni başlatabilirsiniz.

Yığında kullanılabilir bellek miktarı sınırlıdır. Yığında çok fazla bellek ayırırsanız, bir StackOverflowException oluşturulur. Bu özel durumdan kaçınmak için şu kuralları izleyin:

  • kullanarak 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ığındaki belleği ayırın. 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[inputLength] : new byte[inputLength];
    

    Not

    Yığında kullanılabilir bellek miktarı kodun çalıştığı 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. Bir başlatıcı veya gibi Span<T>.Clearbir stackalloc yöntemle kullanılmadan önce başlatmanız gerekir.

Önemli

tarafından stackalloc ayrılan belleği başlatmama işlecinden new önemli bir farktır. işleci kullanılarak new ayrılan bellek 0 bit desenine başlatılır.

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 etmiyorsa bir span için yığın ayrılmış depolamayı kullanabilir.

Güvenlik

kullanarak stackalloc , ortak dil çalışma zamanında (CLR) arabellek taşması algılama özelliklerini otomatik olarak açar. Çalışma zamanı bir arabellek taşması algılarsa, kötü amaçlı kodun çalışma olasılığını azaltmak için işlemi mümkün olan en kısa sürede sonlandırır.

C# dili belirtimi

Daha fazla bilgi için C# dil belirtimininYığın ayırma bölümüne bakın.

Ayrıca bkz.