stackalloc (C# リファレンス)stackalloc (C# Reference)

stackalloc キーワードは、スタックにメモリ ブロックを割り当てるために使用されます。The stackalloc keyword is used to allocate a block of memory on the stack.

Span<int> block = stackalloc int[100];

割り当てられたブロックを int* ではなく Span<T> に割り当てると、安全なブロックでスタックを割り当てることができます。Assigning the allocated block to a Span<T> instead of an int* allows stack allocations in a safe block. unsafe コンテキストは必須ではありません。The unsafe context is not required.

解説Remarks

このキーワードは、ローカル変数初期化子でのみ有効です。The keyword is valid only in local variable initializers. 次のコードはコンパイル エラーになります。The following code causes compiler errors.

int* block;
// The following assignment statement causes compiler errors. You
// can use stackalloc only when declaring and initializing a local
// variable.
block = stackalloc int[100];
Span<int> span;
// The following assignment statement causes compiler errors. You
// can use stackalloc only when declaring and initializing a local
// variable.
span = stackalloc int[100];

C# 7.3 以降では、stackalloc 配列に対して配列初期化子構文を使うことができます。Beginning with C# 7.3, you can use array initializer syntax for stackalloc arrays. 次のすべての宣言では、値が整数 123 である 3 つの要素を含む配列が宣言されています。All the following declarations declare an array with three elements whose values are the integers 1, 2, and 3. 2 回目の初期化でメモリを ReadOnlySpan<T> に割り当て、メモリを変更できないことを示します。The second initialization assigns the memory to a ReadOnlySpan<T>, indicating that the memory cannot be modified.

// Valid starting with C# 7.3
Span<int> first = stackalloc int[3] { 1, 2, 3 };
ReadOnlySpan<int> second = stackalloc int[] { 1, 2, 3 };
Span<int> third = stackalloc[] { 1, 2, 3 };

ポインター型が使用される場合、stackalloc には unsafe コンテキストが必要です。When pointer types are involved, stackalloc requires an unsafe context. 詳細については、「アンセーフ コードとポインター」を参照してください。For more information, see Unsafe Code and Pointers.

stackalloc は、C ランタイム ライブラリの _alloca に似ています。stackalloc is like _alloca in the C run-time library.

使用例Examples

次の例では、フィボナッチ数列の最初の 20 個の数値を計算して表示します。The following example calculates and displays the first 20 numbers in the Fibonacci sequence. それぞれの数値が、前の 2 つの数値の和になっています。Each number is the sum of the previous two numbers. このコードでは、int 型の要素を 20 個保持できるサイズのメモリ ブロックが、ヒープではなくスタックに割り当てられ、In the code, a block of memory of sufficient size to contain 20 elements of type int is allocated on the stack, not the heap. そのブロックのアドレスは Span fib に格納されます。The address of the block is stored in the Span fib. このメモリは、ガベージ コレクションの対象にはならないため、fixed を使用して固定する必要はありません。This memory is not subject to garbage collection and therefore does not have to be pinned (by using fixed). メモリ ブロックの有効期間は、そのブロックを定義するメソッドの有効期間に限定されます。The lifetime of the memory block is limited to the lifetime of the method that defines it. メソッドから制御が戻る前に、メモリを解放することはできません。You cannot free the memory before the method returns.

const int arraySize = 20;
Span<int> fib = stackalloc int[arraySize];
// The sequence begins with 1, 1.
fib[0] = fib[1] = 1;
for (int i = 2; i < arraySize; ++i)
{
    // Sum the previous two numbers.
    fib[i] = fib[i-1] + fib[i-2];
}
for (int i = 0; i < arraySize; ++i)
{
    Console.WriteLine(fib[i]);
}
/* Output:
   1
   1
   2
   3
   5
   8
   13
   21
   34
   55
   89
   144
   233
   377
   610
   987
   1597
   2584
   4181
   6765
 */

次の例では、整数の stackalloc 配列を、要素ごとに 1 ビットが設定されているビット マスクに初期化しています。The following example initializes a stackalloc array of integers to a bit mask with one bit set in each element. これは、C# 7.3 以降で使用可能な新しい初期化子の構文を示しています。This demonstrates the new initializer syntax available starting in C# 7.3:

ReadOnlySpan<int> mask = stackalloc[] {
    0b_0000_0000_0000_0001,
    0b_0000_0000_0000_0010,
    0b_0000_0000_0000_0100,
    0b_0000_0000_0000_1000,
    0b_0000_0000_0001_0000,
    0b_0000_0000_0010_0000,
    0b_0000_0000_0100_0000,
    0b_0000_0000_1000_0000,
    0b_0000_0001_0000_0000,
    0b_0000_0010_0000_0000,
    0b_0000_0100_0000_0000,
    0b_0000_1000_0000_0000,
    0b_0001_0000_0000_0000,
    0b_0010_0000_0000_0000,
    0b_0100_0000_0000_0000,
    0b_1000_0000_0000_0000
};

for (int i = 0; i < 16; i++)
    Console.WriteLine(mask[i]);
/* Output:
   1
   2
   4
   8
   16
   32
   64
   128
   256
   512
   1024
   2048
   4096
   8192
   16384
   32768
 */

セキュリティSecurity

アンセーフ コードはセーフ コードよりも安全性が低いため、可能な限り Span<T> または ReadOnlySpan<T> を使用してください。You should use Span<T> or ReadOnlySpan<T> when possible because unsafe code is less secure than safe alternatives. ポインターと共に使用したとしても、stackalloc を使用すると、共通言語ランタイム (CLR) のバッファー オーバーラン検出機能が自動的に有効になります。Even when used with pointers, the use of stackalloc automatically enables buffer overrun detection features in the common language runtime (CLR). バッファー オーバーランが検出されると、悪意のあるコードが実行される可能性を最小限に抑えるために、プロセスはできる限り迅速に終了されます。If a buffer overrun is detected, the process is terminated as quickly as possible to minimize the chance that malicious code is executed.

C# 言語仕様C# language specification

詳細については、「C# 言語の仕様」を参照してください。For more information, see the C# Language Specification. 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。The language specification is the definitive source for C# syntax and usage.

関連項目See also