4

我被告知不要使用堆栈分配的数组,因为堆栈是一种宝贵的资源。其他人向我建议,实际上使用堆栈分配的数组是完全可以的,只要数组相对较小。

我想有一个一般的经验法则:什么时候应该使用堆栈分配的数组?什么时候应该使用堆分配数组?

4

5 回答 5

3

虽然您的所有内存都是有限的,但即使在今天拥有大量 RAM 和虚拟内存的情况下,仍然存在限制。但是,它相当大,尤其是与堆栈相比,堆栈可以是从小型嵌入式系统上的几 kb 到 PC 上几兆字节的任何内容。

除此之外,还有一个关于您如何使用它以及用于什么的问题。例如,如果你想从一个函数返回一个“数组”,它不应该在堆栈上。

一般来说,如果可以的话,我会说尽量保持堆栈上的数组很小。如果您要在堆栈上创建一个包含数千个条目的数组,您应该停下来考虑一下您想要它做什么。

于 2012-08-17T11:07:01.307 回答
2

这取决于您的平台。

如今,如果在流行的 x64 平台上工作,您真的不必担心它。

根据您使用的操作系统,您可以检查允许用户态进程使用多少堆栈空间和多少堆空间。

例如,类 UNIX 系统具有软限制和硬限制。有些你可以加速,有些你不能。

底线是你通常不需要担心这些事情。当你需要知道的时候,你通常与你将要开发的平台紧密相连,以至于你知道所有这些细节。

希望我回答了你的问题。如果您需要特定值,请指定您的确切硬件、操作系统和用户权限。

于 2012-08-17T11:10:27.477 回答
1

全局变量和静态变量的作用域将贯穿一个进程的整个生命周期。这些变量的内存将在进程启动时分配,并且仅在进程退出时才会释放。

但是局部变量(堆栈变量)仅对定义它的函数具有作用域。调用函数时将分配内存,一旦控制从函数退出,它将被释放。

动态内存的主要目的是创建用户定义范围的变量。如果你想控制变量的范围,你可以x在一个函数中为一个变量分配内存,然后将引用(地址)传递给你想要的多个函数,最后你可以释放它。

因此,借助动态分配的内存,我们可以创建一个范围高于局部变量但小于全局或静态变量的变量。

除此之外,如果大小非常高,最好选择动态内存,如果架构包含内存限制。

于 2012-08-17T12:30:30.817 回答
1

这个问题的答案取决于上下文。例如,当您为操作系统内核编写代码时,堆栈可能非常有限,在堆栈帧中分配超过一千字节可能会导致问题。

在现代消费者系统中,可用于堆栈的空间通常非常大。过去的一个问题系统是地址空间是有限的,一旦堆栈被分配了一个地址,它就不能在堆栈增长方向上比地址空间中的下一个对象增长得更远,而不管物理内存的可用性如何或地址空间中其他地方的虚拟内存。对于今天的地址空间来说,这已经不是问题了。

通常,可以在堆栈帧中分配兆字节的空间,这样做既便宜又容易。但是,如果调用了许多分配大量空间的例程,或者递归调用了一个或几个分配大量空间的例程,则可能会出现问题,因为使用了太多空间,遇到了一些限制(例如地址空间或物理内存)。

当然,从堆中分配空间并不能缓解遇到物理内存限制的情况。所以只有消耗堆栈可用的地址空间的问题才与使用堆栈还是堆的问题有关。

main一个简单的测试这是否是一个问题是在您的例程中插入大量堆栈空间的使用。如果您使用额外的堆栈空间,并且您的应用程序在正常使用大量堆栈空间的负载下仍能正常运行,那么,当您在 中删除此人为保留时main,您将有足够的余量。

更好的方法是计算程序可以使用的最大值,并将其与系统可用的堆栈空间进行比较。但这对于今天的软件来说并不容易。

如果您遇到堆栈空间限制,您的链接器或操作系统可能会选择提供更多可用空间。

于 2012-08-17T11:14:38.820 回答
0

使用堆分配内存的充分理由是将其所有权传递给其他一些函数/结构。另一方面,堆栈为您提供免费的内存管理,您不能忘记从堆栈中释放内存,而使用堆则存在泄漏风险。

如果您创建一个仅用于本地使用的数组,则使用的大小标准,但是很难给出确切的大小,超过该大小的内存应该在堆上分配。可以说几百字节足以移动到堆中,对于其他一些人来说,它会更少或更多。

于 2012-08-17T11:06:14.303 回答