stackalloc 運算式 (C# 參考)
stackalloc
運算式會在堆疊上配置記憶體區塊。 在方法執行期間建立的堆疊配置的記憶體區塊,會在該方法傳回時自動被捨棄。 您無法明確釋放使用 stackalloc
配置的記憶體。 堆疊配置的記憶體區塊不受垃圾收集限制,而且不需要使用fixed
語句釘選。
您可以將運算式的結果 stackalloc
指派給下列其中一種類型的變數:
System.Span<T> 或 System.ReadOnlySpan<T> ,如下列範例所示:
int length = 3; Span<int> numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; }
當您將堆疊配置的記憶體區塊指派至 Span<T> 或 ReadOnlySpan<T> 變數時,您不需要使用 unsafe 內容。
當您處理那些類型時,您可以使用條件式或指派運算式中的
stackalloc
運算式,如下列範例所示:int length = 1000; Span<byte> buffer = length <= 1024 ? stackalloc byte[length] : new byte[length];
每當允許 或 ReadOnlySpan<T> 變數時 Span<T> ,您可以在其他運算式內使用
stackalloc
運算式,如下列範例所示: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<T> 或 ReadOnlySpan<T> 類型來處理堆疊配置的記憶體。
指標類型,如下列範例所示:
unsafe { int length = 3; int* numbers = stackalloc int[length]; for (var i = 0; i < length; i++) { numbers[i] = i; } }
如先前的範例所示,您在使用指標類型時必須使用
unsafe
內容。在指標類型的情況下,您只能在區域變數宣告中使用
stackalloc
運算式來初始化變數。
堆疊上可用的記憶體數量受到限制。 如果您在堆疊上配置太多記憶體, StackOverflowException 則會擲回 。 若要避免此問題,請遵循下列規則:
限制您使用
stackalloc
配置的記憶體數量。 例如,如果預期的緩衝區大小低於特定限制,您會在堆疊上配置記憶體;否則,請使用必要長度的陣列,如下列程式碼所示:const int MaxStackLimit = 1024; Span<byte> buffer = inputLength <= MaxStackLimit ? stackalloc byte[MaxStackLimit] : new byte[inputLength];
注意
因為堆疊上可用的記憶體數量取決於執行程式碼的環境,所以當您定義實際限制值時,請謹慎使用。
避免使用
stackalloc
內部迴圈。 在迴圈外部配置記憶體區塊,並在迴圈內重複使用。
新配置記憶體的內容尚未被定義。 您應該先將其初始化,再使用。 例如,您可以使用 Span<T>.Clear 方法,將所有專案設定為 類型的 T
預設值。
您可以使用陣列初始化運算式語法來定義新配置的記憶體內容。 下列範例示範進行該操作的數種方法:
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
必須是 Unmanaged 類型 ,而且 E
必須評估為非負 整數 值。
安全性
使用 stackalloc
會自動啟用 Common Language Runtime (CLR) 中的緩衝區滿溢偵測功能。 如果偵測到緩衝區滿溢,會盡快終止處理序,將執行惡意程式碼的機會降到最低。
C# 語言規格
如需詳細資訊,請參閱C# 語言規格的堆疊配置一節和巢狀內容中的允許 stackalloc
功能提案附注。