stackalloc 表达式在堆栈上分配一块内存。在方法执行期间创建的堆栈分配内存块在该方法返回时自动丢弃。你不能显式地释放用 stackalloc 分配的内存。堆栈分配的内存块不受垃圾收集的约束,也不必用固定语句固定。
可以将 stackalloc 表达式的结果赋值给以下类型之一的变量:
- System . Span < T > 或 System . ReadOnlySpan < T >,如下例:
int Zhs长度 = 3;
Span < int > Zhss = stackalloc int [ Zhs长度 ];
for ( int i = 0 ; i < Zhss . Length ; i++ )
{
Zhss [ i ] = i;
}
foreach ( int i in Zhss )
{
Console . Write ( i );
}
输出:
012
当您将堆栈分配的内存块分配给 Span < T > 或 ReadOnlySpan < T > 变量时,您不必使用 unsafe 上下文。
当处理这些类型时,可以在条件表达式或赋值表达式中使用 stackalloc 表达式,如下例所示:
Zhs长度 = 1000;
Span < byte > HCQ = Zhs长度 < 1024 ? stackalloc byte [ Zhs长度 ] : new byte [ Zhs长度 ];
Console . WriteLine ( HCQ . Length );
只要允许使用 stackalloc 或 Span < T > 变量,就可以在其他表达式中使用 ReadOnlySpan < T > 表达式或集合表达式,如下例所示:
Span < int > ZhsSpan = stackalloc [ ] { 1 , 3 , 5 , 7 , 9 };
int ind = ZhsSpan . IndexOfAny ( stackalloc [ ] { 5 , 7 } );
Console . WriteLine ( ind ); // 输出 2
ZhsSpan = [ 1 , 2 , 3 , 4 , 5 , 6 ];
ind = ZhsSpan . IndexOfAny ( [ 4 , 5 ] );
Console . WriteLine ( ind ); // 输出 3
备注:建议尽可能使用 Span < T > 或 ReadOnlySpan < T > 类型来处理堆栈中分配的内存。
- 指针类型
需要在菜单“项目”→“工程 和属性”→“生成”→“常规”中选定“不安全代码”中的“允许使用“unsafe”关键字编译的代码。”一项:
unsafe
{
int Zhs长度 = 3;
int* Zhs = stackalloc int [ Zhs长度 ];
for ( int i = 0 ; i < Zhs长度 ; i++ )
{
Zhs [ i ] = i;
}
}
如前面的示例所示,在使用指针类型时必须使用 unsafe 上下文。
对于指针类型,只能在局部变量声明中使用 stackalloc 表达式来初始化变量。
堆栈上可用的内存量存在限制。如果在堆栈上分配过多的内存,会引发 StackOverflowException。为避免这种情况,请遵循以下规则:
- 限制使用 stackalloc 分配的内存量。例如,如果预期的缓冲区大小低于特定限制,则在堆栈上分配内存;否则,使用所需长度的数组,如以下代码所示:
const int ZD堆栈大小 = 1024;
Span < byte > buffer = Zhs输入长度 <= ZD堆栈大小 ? stackalloc byte [ MaxStackLimit ] : new byte [ Zhs输入长度 ];
备注:由于堆栈上可用的内存量取决于执行代码的环境,因此在定义实际限值时请持保守态度。
- 避免在循环内使用 stackalloc。在循环外分配内存块,然后在循环内重用它。
新分配的内存的内容未定义。应使用 stackalloc 初始值设定项初始化它,或者使用方法(如 Span < T > . Clear 使用前)。
重要:不初始化由 stackalloc 分配的内存是 new 操作符的一个重要区别。使用 new 操作符分配的内存初始化为 0 位模式。
可以使用数组初始值设定项语法来定义新分配的内存的内容。下面的示例演示执行此操作的各种方法:
Span < int > first = stackalloc int [ 3 ] { 1 , 2 , 3 };
Span < int > second = stackalloc int [ ] { 1 , 2 , 3 };
ReadOnlySpan < int > third = stackalloc [ ] { 1 , 2 , 3 };
// 使用集合表达式
Span<int> fourth = [ 1 , 2 , 3 ];
ReadOnlySpan<int> fifth = [ 1 , 2 , 3 ];
在表达式 stackalloc T [ E ] 中,T 必须是非托管类型,并且 E 必须求值为非负整型值。当使用集合表达式语法初始化 span 时,如果不违反 ref 安全,编译器可能会为 span 使用堆栈分配的存储。
安全
使用 stackalloc 会自动启用公共语言运行时(CLR)中的缓冲区溢出检测功能。如果检测到缓冲区溢出,则会尽快终止进程,以尽量减少执行恶意代码的机会。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。