何时需要在C#中使用stackalloc关键字?

27
stackalloc关键字提供了什么功能?何时和为什么我会想要使用它?

@Paul:我只是修改了问题,增加了一些内容。你最初的措辞实际上并没有什么问题。 - TheTXI
有人能否说明一下,在回答中何时需要使用不安全操作? - dance2die
https://dev59.com/bHRA5IYBdhLWcg3w6SRH - Mauricio Scheffer
7个回答

20

MSDN

在不安全代码的上下文中使用,以在堆栈上分配一块内存。

C# 的主要特点之一是您通常不需要直接访问内存,就像您在 C/C++ 中使用 mallocnew 一样。但是,如果您真的想显式分配一些内存,您可以这样做,但 C# 认为这是“不安全的”,因此只有在编译时使用 unsafe 设置才能这样做。 stackalloc 允许您分配此类内存。

您几乎肯定不需要为编写托管代码而使用它。在某些情况下,您可能会通过直接访问内存来编写更快的代码-基本上它允许您使用指针操作,这适用于某些问题。除非您有一个具体的问题并且不安全的代码是唯一的解决方案,否则您 可能 永远不需要使用它。


2
StackOverflow是这样构建的,以便那些在互联网上进行搜索的人会在这里找到答案(只需要先提出问题)。 - TheTXI
很不幸,你听起来有点粗鲁 :) 或许这个人不理解在栈和堆上分配内存的区别。你的回答显而易见且没必要这样做。 - Adam Robinson
Adam,我并不完全同意。他可能会用不同的措辞来提问,例如:“我什么时候需要使用stackalloc关键字?” - Razzie
1
你是指这个问题标题的确切措辞吗? - Adam Robinson
2
“is not managed by the CLR” - 这是正确的,但非常误导人,因为由于它在堆栈上分配,它会在作用域/方法结束时自动被删除,不需要任何进一步的垃圾回收。 - Konrad Rudolph
显示剩余3条评论

17

使用stackalloc可以在堆栈上分配数据,这可以用于避免在方法内重复创建和销毁值类型数组所产生的垃圾。

public unsafe void DoSomeStuff()
{
    byte* unmanaged = stackalloc byte[100];
    byte[] managed = new byte[100];

    //Do stuff with the arrays

    //When this method exits, the unmanaged array gets immediately destroyed.
    //The managed array no longer has any handles to it, so it will get 
    //cleaned up the next time the garbage collector runs.
    //In the mean-time, it is still consuming memory and adding to the list of crap
    //the garbage collector needs to keep track of. If you're doing XNA dev on the
    //Xbox 360, this can be especially bad.
}

请注意,由于逃逸分析的作用,即使是 managed 变量,有时也可能被分配到栈上。 - user1804599

9

保罗,

正如这里的每个人所说的那样,该关键字指示运行时在堆栈上分配而不是堆。如果您想了解确切含义,请查看本文


3

2
大多数其他答案都关注于OP问题中的“什么功能”部分。
我认为这会回答何时和为什么:
你何时需要它?
用于具有多个小数组的缓存局部性的最佳最坏情况性能。
在平均应用程序中,您不需要此功能,但对于实时敏感场景,它提供更确定性能:没有涉及垃圾回收,并且几乎可以保证缓存命中。
(因为最坏情况性能比平均性能更重要。)
请记住,.net中的默认堆栈大小很小!
(我认为普通应用程序为1MB,ASP.net为256kb?)
实际用途可以包括实时音频处理。

2

stackalloc指示.NET运行时在堆栈上分配内存。


0

就像 Steve 指出的那样,它只在不安全代码上下文中使用(例如,当您想要使用指针时)。

如果您的 C# 应用程序中不使用不安全代码,则永远不需要使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接