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];
每當允許 Span<T> 或 ReadOnlySpan<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<int> numbers2 = [1, 2, 3, 4, 5, 6]; var ind2 = numbers2.IndexOfAny([2, 4, 6, 8]); Console.WriteLine(ind2); // 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 };
// Using collection expressions:
Span<int> fourth = [1, 2, 3];
ReadOnlySpan<int> fifth = [1, 2, 3];
在運算式 stackalloc T[E]
中,T
必須是非受控類型,且 E
必須評估為非負數的 int 值。 當您使用集合運算式語法來初始化範圍時,編譯器可能會在不違反 ref safety 的情況下,針對範圍使用堆疊配置儲存體。
安全性
使用 stackalloc
會自動啟用 Common Language Runtime (CLR) 中的緩衝區滿溢偵測功能。 如果偵測到緩衝區滿溢,會盡快終止處理序,將執行惡意程式碼的機會降到最低。
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格的堆疊配置一節,以及在巢狀內容中允許 stackalloc
功能提案附註。