c#如果span<T>(memory<T>)引用堆栈上的缓冲区会发生什么 [英] c# What happen if span<T>(memory<T>) refers to buffers on stack

查看:20
本文介绍了c#如果span<T>(memory<T>)引用堆栈上的缓冲区会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET Standard 2.1 引入了一项新功能,您可以控制"内存块而不是复制它们:Span内存.

.NET Standard 2.1 has introduced a new feature where you can "control" the memory blocks instead of copying them: Span or Memory.

在文档示例中,我注意到可以引用堆栈缓冲区:

In the docs example, I noticed that it is possible to refer to a stack buffer:

byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
   stackSpan[ctr] = data++;

据我所知,进程的堆栈内存是有限的(1MB 或 4MB),我们无法手动释放它.

As far as I know, stack memory for a process is limited (1MB or 4MB), and we cannot manually release it.

所以我想创建一个 MemorySpan 会以某种方式固定"堆栈上的内存位置,以便我们可以索引它?但这不是可能导致堆栈溢出的堆栈泄漏的潜在情况吗?由于堆栈上的数组应该与 MemorySpan 一样长.

So I guess creating a Memory<T> or Span<T> will somehow "Pin" the memory location on stack thus we can index it? But wouldn't that be a potenial case of stack-leak which might result in stack-overfolow? Since the array on stack should live as long as Memory<T> or Span<T>.

推荐答案

这是安全的,因为 Span 的生命周期将与堆栈分配的数组相同或更短.

It is safe as Span's lifetime will be same or shorter than stack-allocated array.

您至少不能直接将 stackalloc 的结果分配给 Memory(我认为即使是不安全的代码也无济于事 - C#:将通用指针转换为数组) 所以将其范围限定为 Span.

You can't assign result of stackalloc to Memory<T> at least directly (I don't think even unsafe code can help - C#: convert generic pointer to array) so scoping this to just Span<T>.

根据链接 您发布的跨度生命周期与其定义的范围相关联:

According to the link you've posted Span lifetime is tied to scope it defined:

Span 是一个引用结构,它分配在堆栈上而不是托管堆上.Ref struct 类型有许多限制,以确保它们无法提升到托管堆,

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.由于结果跨度将在同一时间(或更早)被销毁,然后堆栈帧包含由 stackalloc 创建的数组.

Note that ref struct makes some operations prohibited including the one you should be concerned about - returning Span<T> from method where stack was allocated. As result span will be destroyed at the same time (or earlier) then stack frame which included array created by 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 中介绍:探索新的 .NET 支柱,作者:Stephen Toub.

This also covered in MSDN Magazine article (January 2018) C# - All About Span: Exploring a New .NET Mainstay by Stephen Toub.

这篇关于c#如果span&lt;T&gt;(memory&lt;T&gt;)引用堆栈上的缓冲区会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆