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ür olduğunda otomatik olarak atılır. ile ayrılan belleği açıkça serbest stackalloc bırakamazsiniz. Yığın tarafından ayrılan bellek bloğu çöp toplamaya tabi değildir ve deyimiyle sabitlenmiş olması fixed gerek değildir.
Bir ifadenin sonucu aşağıdaki stackalloc türlerden biri olan bir değişkene at uygun olabilir:
Aşağıdaki örnekte olduğu gibi C# 7.2 System.Span<T> System.ReadOnlySpan<T> veya ile başarak:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }Bir veya değişkenine yığın tarafından ayrılan bellek bloğu atarken güvenli olmayan bir bağlam kullanmak Span<T> zorunda ReadOnlySpan<T> değildir.
Bu türlerle birlikte, aşağıdaki örnekte de olduğu gibi koşullu veya atama ifadelerinde
stackallocbir ifade kullanabilirsiniz:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];C# 8.0'dan başarak, aşağıdaki örnekte de olduğu gibi, bir veya değişkenine izin verilmiyorsa diğer ifadelerin içinde
stackallocSpan<T> bir ifade ReadOnlySpan<T> kullanabilirsiniz:Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 }; var ind = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 }); Console.WriteLine(ind); // output: 1Not
Mümkün olduğunda yığın Span<T> tarafından ReadOnlySpan<T> ayrılan bellekle çalışmak için veya türlerini kullanmanız önerilir.
Aşağıdaki örnekte deolduğu 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 de olduğu gibi, işaretçi
unsafetürleriyle çalışmanız için bir bağlam kullan gerekir.İşaretçi türleri söz konusu olursa, değişkeni başlatmak için yalnızca yerel değişken
stackallocbildiriminde bir ifade kullanabilirsiniz.
Yığında kullanılabilir bellek miktarı sınırlıdır. Yığında çok fazla bellek StackOverflowException ayırırsanız, bir atlanır. Bunu önlemek için aşağıdaki kuralları izleyin:
ile ayırarak bellek miktarını
stackallocsınırla. Örneğin, amaçlanan arabellek boyutu belirli bir sınırın altında ise, belleği yığına ayırırsanız; aksi takdirde, aşağıdaki kodda da olduğu 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 yürütül olduğu ortama bağlı olduğundan, gerçek sınır değerini tanımlarken tutucu olmak.
Döngülerin
stackallociçinde kullanmaktan kaçının. Bellek bloğuna döngü dışında ayırma ve döngü içinde yeniden kullanma.
Yeni ayrılan belleğin içeriği tanımlanmamıştır. Kullanımdan önce başlatmalısiniz. Örneğin, tüm öğeleri Span<T>.Clear türünün varsayılan değerine ayaran yöntemini T kullanabilirsiniz.
C# 7.3'den başlayarak, yeni ayrılan belleğin içeriğini tanımlamak için dizi başlatıcı söz dizimi kullanabilirsiniz. Aşağıdaki örnekte bunu yapmak için çeşitli yollar gösterildi:
Span<int> first = stackalloc int[3] { 1, 2, 3 };
Span<int> second = stackalloc int[] { 1, 2, 3 };
ReadOnlySpan<int> third = stackalloc[] { 1, 2, 3 };
stackalloc T[E] T ifadesinde, bir unmanaged türü olmalı ve negatif olmayan bir E int değeri olarak değerlendirin.
Güvenlik
kullanımı, ortak stackalloc dil çalışma zamanında (CLR) arabellek taşması algılama özelliklerini otomatik olarak sağlar. Arabellek taşması algılanırsa, kötü amaçlı kodun yürütülme ihtimalini 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 belirtimlerinin Yığın ayırma bölümüne ve İç içe bağlamlarda izin ver özellik stackalloc teklifi notlarına bakın.