问题标签 [stackalloc]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
55 浏览

c# - 为什么我在堆栈中有填充?

我试图了解堆栈(段)是如何工作的,并认为它只会一个接一个地分配每个元素(变量、字节、我想要分配的任何东西)。但是在编写了以下代码后,我发现了一些奇怪的东西。

在查看内存时,我注意到我的整数远离堆栈分配的指针(在正方形中,您可以看到我分配的整数的内存。)

在此处输入图像描述

问题

  • 为什么没有在我的数组之后分配整数内存?
  • 中间的那条线包含什么信息?( 13 9a 3d 08 31 04 00 00)

笔记

我的整数始终与我的数组相距“5 个整数”,这意味着每当我将代码更改为此:

然后我的整数实际上被覆盖了。

0 投票
2 回答
3643 浏览

c# - 为什么零长度的 stackalloc 让 C# 编译器乐于允许有条件的 stackalloc?

下面的“修复”让我很困惑;这里的场景是根据大小有条件地决定是使用堆栈还是租用缓冲区 - 这是一个非常利基但有时是必要的优化,但是:使用“明显”的实现(第 3 号,推迟明确的分配,直到我们真正想要分配它),编译器向 CS8353 抱怨:

'Span<int>' 类型的 stackalloc 表达式的结果不能在此上下文中使用,因为它可能暴露在包含方法之外

简短的复制(完整的复制如下)是:

我在这里唯一能想到的是,编译器确实在标记stackalloc正在转义stackalloc发生事件的上下文,并且挥舞着一个标记说“我无法证明这在该方法的后面是否安全” ,但是通过stackalloc[0]在开始时,我们将“危险”上下文范围推得更高,现在编译器很高兴它永远不会逃脱“危险”范围(即它实际上从未离开方法,因为我们正在声明在顶部范围内)。这种理解是否正确,就可以证明的内容而言,这只是编译器的限制?

(对我来说)真正有趣的是,从根本上讲,无论如何= stackalloc[0]都是无操作的,这意味着至少在编译后的形式中,工作数字 1与失败的数字 2 相同。= stackalloc[0]= default

完整再现(也可在 SharpLab 上查看 IL)。

0 投票
1 回答
71 浏览

c# - 为什么不能将`stackalloc`表达式分配给`Span`参数?

考虑以下方法(小提琴):

我不明白为什么param = stackalloc int[10];会产生错误:

stackalloc不能在此上下文中使用类型为“Span”的表达式的结果,因为它可能会暴露在包含方法之外

Span是一个ref struct但是(尽管它的名字)它仍然是一个值类型,所以任何修改param都不会反映在调用者对象上。

我认为是param一个具有初始值的局部变量,我不明白为什么test2编译而test没有。

stackalloc int[10]in的返回值如何test逃出方法的作用域?

0 投票
1 回答
61 浏览

c# - 当我在 C# 中将 `ref` 值分配给 `out` 参数时会发生什么?

我正在编写一个检索二进制数据并支持将其一般转换为原始类型的类。它应该尽可能高效。这是它现在的样子:

由于我正在使用大量内存,并且我的代码将执行许多小型读取操作。我想尽量减少复制内存的次数。

ReadBytes实现将a)在堆上已经存在的数组的一部分上创建一个跨度,或者b) stackalloc一个缓冲区并用来自远程源的数据填充它(取决于我将使用的数据)。关键是,它不会自己在堆上分配任何东西。

我希望我的TryRead<T>方法返回对跨度内存的类型化引用,而不是将该内存复制到新值中,我想知道这是否可能。我注意到我不能在不初始化参数的情况下为参数赋值refout但我可以在之后,如果我们假设我正在分配一个引用,这毫无意义。

我想我要问的是,这段代码到底发生了什么?我是返回对现有值的引用,还是将该值复制到新的堆栈分配的值中?堆栈分配和堆分配跨度的行为会有什么不同?T如果使用堆分配的跨度,GC 会知道在移动数据时更新类型的引用吗?

0 投票
1 回答
79 浏览

c# - stackalloc espression 的返回类型是什么?

我正在玩stackalloc并发现它的返回类型有很多奇怪之处。以下是一些使用示例stackalloc<float>

1.隐式输入返回float*

2.声明 afloat*并稍后设置它 usingstackalloc不会编译:

3.float*在初始化的同时声明就可以了:

4.类似的行为发生在Span<float>

这工作得很好:

但这不会编译:

5.Span<float>使整个情况更加奇怪的是, and or之间没有隐式转换,float*反之亦然。

那么返回的究竟是什么stackalloc float[1]?为什么会出现上述行为?

此代码是使用 VS 2019 C# 版本 9.0、.NET 5 编写的。