c#如果span(memory)引用堆栈上的缓冲区会发生什么
作者:互联网
.NET Standard 2.1引入了一项新功能,您可以在其中“控制”内存块而不用复制它们:Span或Memory.
在docs示例中,我注意到可以引用堆栈缓冲区:
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会以某种方式“固定”堆栈上的内存位置,以便我们对其进行索引吗?但这不是堆栈泄漏的潜在情况,它可能导致堆栈溢出吗?
由于堆栈上的阵列应与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>.来自分配堆栈的方法.结果,将同时(或更早)销毁跨度,然后销毁包含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;
}
Stephen Toub的《 MSDN杂志》文章(2018年1月)C# – All About Span: Exploring a New .NET Mainstay也对此进行了介绍.
标签:net-standard,memory,stack-overflow,c 来源: https://codeday.me/bug/20191108/2007574.html