英文:
How does the Span<T> type wrap around heap-allocated arrays if it's a stack-allocated value type in .NET Core CLR?
问题
Span<T>如何包装堆分配的数组,如果它应该是堆栈分配的值类型?
阅读MSFT关于Span<T>类型的文档时,我遇到了以下内容:
> 当它包装数组时,Span<T>可以包装整个数组,就像在Span<T>和内存部分的示例中所做的那样。因为它支持切片,Span<T>也可以指向数组中的任何连续范围。
这听起来有些令人困惑,因为Span<T>类型被定义为在堆栈上分配的ref结构,而不是托管堆。
英文:
How can Span<T> wrap around a heap allocated Array if it is supposed to be a stack allocated value type?
Reading through the MSFT documentation on the Span<T> type, I came across the following:
This sounds somewhat confusing as the Span<T> type is defined as a ref struct allocated on the stack rather than managed heap.
答案1
得分: 2
Span<T>
指向的是存储在其内部的指针,受到严格限制,
而指针指向的内容可以是任何位置。
Span<T>
不包装其指向的实际内存区域,它仅使用内部指针和大小字段来指向它。
Span
上的限制是为了防止指针从堆栈中泄漏,因为它也可以指向不允许从堆栈中泄漏的堆栈分配的内存。
另一方面,Memory<T>
只允许其指针是数组引用,由于数组是引用类型对象(类),所以可以显然存储在任何地方。
为了澄清:这里的“堆栈”指的是每个C#函数调用中使用的IL中的逻辑堆栈,用于存储其参数、变量和工作区,而不是通常用于实现的内存中的物理堆栈。这两者是正交的,尽管它们通常是一致的:CLR理论上可以将逻辑堆栈存储在物理堆上,并在物理堆栈上分配引用类型对象。
英文:
You appear to be mixing up two different things:
- the pointer stored inside the
Span<T>
, which is indeed heavily restricted, - what that points to, which could be absolutely anywhere.
Span<T>
does not wrap the actual area of memory it points to. It merely points to it using internal pointer and size fields.
The restrictions on Span
are so that the pointer does not leak from the stack, as it can also point to stack-allocated memory which is not allowed to leak out of the stack.
Memory<T>
on the other hand, only allows its pointer to be an array reference, which can obviously be stored anywhere as arrays are reference-type objects (classes).
For clarity: the stack here refers to the logical stack in IL used by every C# function call to store its parameters, variables and working area, not the physical stack in memory commonly used to implement that. These two things are orthogonal, although they usually coincide: it is theoretically possible that the CLR could store the logical stack on the physical heap, and for it to allocate reference-type objects on the physical stack.
答案2
得分: 0
"Span"的Microsoft描述在我看来真的很糟糕。它只会让人更难理解。我认为他们试图以一种不涉及低级语言的方式来解释这个概念,但他们彻底失败了(在我看来)。
实际上,"Span"是一个非常简单的概念。它是对内存片段的视图。这块内存可以位于任何地方:栈、堆,甚至一些内存映射的I/O。"Span"仅包含内存的起始地址和元素数量(计数)。在许多语言中,这可能是字节,但在C#中,"Span"可以是复杂类型。
因此,它是一种非拥有的简单类型,并且可以轻松高效地存储在“堆栈”上。
在C#中,他们为这种类型提供了各种安全性和实用功能,但基本上它仍然是这种简单的视图。
英文:
The Microsoft description of Span
is really bad imho. It only makes it harder to understand. I think they tried to explain it in a way that people without low level language would understand the concept or something like that. But they failed utterly (imho)
A Span
is actually a very simple concept. It's a view on a piece of memory. That memory can be anywhere: stack, heap, heck even on some memory mapped io. All the Span
holds is the starting address of the memory and the amount (count) of elements. In a number of languages that would be bytes, but C# Span
can be complex types.
So it's a non-owning simple type and can easily and efficiently be stored on the "stack".
In C# they put all kinds of safeties and utility in the type, but in the basis it's still that simple view.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论