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 stackalloc
ayrılan belleği açıkça boşaltamazsınız. Yığına ayrılan bellek bloğu çöp toplamaya tabi değildir ve birfixed
deyimle 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
stackalloc
ayı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 T
varsayı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.