c# 如果 span<T>(memory<T>) 引用堆栈上的缓冲区会发生什么
c# What happen if span<T>(memory<T>) refers to buffers on stack
.NET Standard 2.1 引入了一项新功能,您可以 "control" 内存块而不是复制它们:Span or Memory.
在文档示例中,我注意到可以引用堆栈缓冲区:
byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
stackSpan[ctr] = data++;
据我所知,一个进程的堆栈内存是有限的(1MB或4MB),我们不能手动释放它。
所以我想创建一个 Memory<T>
或 Span<T>
会以某种方式 "Pin" 堆栈上的内存位置因此我们可以索引它?但这不会是可能导致堆栈溢出的潜在堆栈泄漏案例吗?
由于堆栈上的数组应该与 Memory<T>
或 Span<T>
.
一样长
这是安全的,因为 Span 的生命周期与堆栈分配的数组相同或更短。
你不能将 stackalloc
的结果至少直接分配给 Memory<T>
(我认为即使是不安全的代码也无济于事 - C#: convert generic pointer to array)所以将其范围限定为 Span<T>
.
根据您发布的link,跨度生命周期与它定义的范围相关:
Span<T>
is a ref struct that is allocated on the stack rather than on the managed heap. Ref struct types have a number of restrictions to ensure that they cannot be promoted to the managed heap,
请注意,ref struct
禁止某些操作,包括您应该关注的操作 - 从分配堆栈的方法返回 Span<T>
。结果 span 将同时(或更早)被销毁,然后堆栈框架包括由 stackalloc
.
创建的数组
static Span<byte> MySpan()
{
Span<byte> span = stackalloc byte[100];
// error CS8352: Cannot use local 'span' in this context because it may
// expose referenced variables outside of their declaration scope
return span;
}
这也在 MSDN 杂志文章(2018 年 1 月)C# - All About Span: Exploring a New .NET Mainstay Stephen Toub 中有所介绍。
.NET Standard 2.1 引入了一项新功能,您可以 "control" 内存块而不是复制它们:Span or Memory.
在文档示例中,我注意到可以引用堆栈缓冲区:
byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
stackSpan[ctr] = data++;
据我所知,一个进程的堆栈内存是有限的(1MB或4MB),我们不能手动释放它。
所以我想创建一个 Memory<T>
或 Span<T>
会以某种方式 "Pin" 堆栈上的内存位置因此我们可以索引它?但这不会是可能导致堆栈溢出的潜在堆栈泄漏案例吗?
由于堆栈上的数组应该与 Memory<T>
或 Span<T>
.
这是安全的,因为 Span 的生命周期与堆栈分配的数组相同或更短。
你不能将 stackalloc
的结果至少直接分配给 Memory<T>
(我认为即使是不安全的代码也无济于事 - C#: convert generic pointer to array)所以将其范围限定为 Span<T>
.
根据您发布的link,跨度生命周期与它定义的范围相关:
Span<T>
is a ref struct that is allocated on the stack rather than on the managed heap. Ref struct types have a number of restrictions to ensure that they cannot be promoted to the managed heap,
请注意,ref struct
禁止某些操作,包括您应该关注的操作 - 从分配堆栈的方法返回 Span<T>
。结果 span 将同时(或更早)被销毁,然后堆栈框架包括由 stackalloc
.
static Span<byte> MySpan()
{
Span<byte> span = stackalloc byte[100];
// error CS8352: Cannot use local 'span' in this context because it may
// expose referenced variables outside of their declaration scope
return span;
}
这也在 MSDN 杂志文章(2018 年 1 月)C# - All About Span: Exploring a New .NET Mainstay Stephen Toub 中有所介绍。