编程语言
首页 > 编程语言> > c#如果span(memory)引用堆栈上的缓冲区会发生什么

c#如果span(memory)引用堆栈上的缓冲区会发生什么

作者:互联网

.NET Standard 2.1引入了一项新功能,您可以在其中“控制”内存块而不用复制它们:SpanMemory.

在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