c# 啥时候在栈上分配数组?
Posted
技术标签:
【中文标题】c# 啥时候在栈上分配数组?【英文标题】: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
可用于强制分配一定数量的字节的堆栈。它有它的用途,但你应该非常确定你需要它 - 大多数程序(尤其是业务线应用程序)不需要它。
堆栈分配的数组在所有恶意软件攻击中占很大比例。
【参考方案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 缺乏某些知识这一事实与运行时的行为相关?在你提问之前澄清你的问题。以上是关于c# 啥时候在栈上分配数组?的主要内容,如果未能解决你的问题,请参考以下文章