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功能提案附注。

另請參閱