【问题标题】:When is array allocated on stack in c#?c# 什么时候在栈上分配数组?
【发布时间】:2015-11-23 07:05:28
【问题描述】:

我一直试图弄清楚什么时候在堆栈上分配了东西,但我不知道如何让数组(或者更确切地说是其中的值)在堆栈上分配;

在这个例子中:

public void foo()
{
    int bar[] = new int [10];
}

10 个 int 结构将分配在堆上,只有指向它们的指针会在堆栈上,对吗?

如何将固定大小的数组放入堆栈?如果我使用我定义的结构怎么办?

如果我想将数组大小作为参数传递给函数怎么办?

据我了解,如果在调用函数时知道大小,则在调用函数时在堆栈上获取任意大小的数组应该没有问题。

我应该为此烦恼吗?据我了解,将这个固定大小的数组放在堆栈上会提高性能,因为没有完成堆分配。

【问题讨论】:

  • Should I be bothered by this? 可能不会。听起来你过早地优化和思考太低了。
  • stackalloc 可用于强制分配一定数量的字节的堆栈。它有它的用途,但你应该非常确定你需要它 - 大多数程序(尤其是业务线应用程序)不需要它。
  • 堆栈分配的数组在所有恶意软件攻击中占很大比例。

标签: c# arrays heap-memory allocation stack-memory


【解决方案1】:

10 个 int 结构将分配在堆上,只有指向它们的指针会在堆栈上,对吗?

是的,正确。

如何将固定大小的数组放入堆栈?如果我使用我定义的结构怎么办?

stackalloc keyword 用于此目的。但是,这仅适用于不安全的上下文,这在大多数情况下是一个相当不必要的限制因素,不值得在性能上进行权衡。

例子:

public void unsafe foo()
{
    int* bar = stackalloc int [10];
}

您必须使用 pointer arithmetic 来访问数组的成员。

如果我想将数组大小作为参数传递给函数怎么办? 据我了解,如果在调用函数时知道大小,则在调用函数时在堆栈上获取任意大小的数组应该没有问题。

按预期工作:

public void unsafe foo(int length)
{
    int* bar = stackalloc int [length];
}

我应该为此烦恼吗?据我了解,将这个固定大小的数组放在堆栈上会提高性能,因为没有完成堆分配。

不,一般不会。除非您处理一些非常具体的性能关键场景,例如繁重的数学计算、加密、压缩等,否则它不会带来真正的好处。

另外,请参阅this question 以了解与性能相关的讨论。

【讨论】:

  • 谢谢,我喜欢人们如何对堆栈溢出的一些琐碎问题给出真正彻底的解释。
  • 除了stackalloc,您还可以在堆栈上分配固定大小的缓冲区。例如:unsafe struct foo { public fixed int bar[10]; }
  • Span<T> 类型的添加意味着不再需要不安全的指针。 public void foo() { Span<int> bar = stackalloc int [10]; }
  • 在编译时大小未知的情况下,为什么甚至可以在堆栈上分配数组?
  • @algo:这是一个问答网站;这听起来像是一个问题的候选人。但是,在您发布问题之前,我会先考虑一下。根据定义,在程序运行之前不会进行分配。为什么 compiler 缺乏某些知识这一事实与运行时的行为相关?在你提问之前澄清你的问题。
猜你喜欢
  • 2012-08-13
  • 1970-01-01
  • 2013-11-24
  • 2017-08-17
  • 2011-03-10
  • 2018-11-11
  • 2013-10-07
  • 2017-01-25
  • 1970-01-01
相关资源
最近更新 更多