在堆栈上使用大变量/数组的缺点

Disadvantages of using large variables/arrays on the stack?

本文关键字:数组 缺点 变量 堆栈      更新时间:2023-10-16

在堆栈上定义大型数组或对象有哪些缺点(如果有的话)?举以下例子:

int doStuff() {
   int poolOfObjects[1500];
   // do stuff with the pool
   return 0;
}

这是否存在性能问题?我听说过堆栈溢出问题,但我认为这个数组不够大。

如果出现堆栈溢出问题

  • 数组大于线程堆栈

  • 呼叫树很深

  • 该函数使用递归

在所有其他情况下,堆栈分配是获取内存的一种非常快速有效的方式。然而,调用大量的构造函数和析构函数可能会很慢,因此,如果您的构造函数/析构函数不是平凡的,那么您可能希望使用寿命更长的池。

正如您所提到的,溢出堆栈是主要问题。即使您的特殊情况不是很大,也要考虑如果函数是递归的会发生什么。

更糟糕的是,如果函数是从递归函数调用的,它可能会被内联,从而导致"意外"的stackerflow问题。(我在使用"英特尔编译器"时多次遇到此问题。)


就性能问题而言,这些问题比猜测的要好。但是,如果堆栈上有一个非常大的数组来分隔其他变量,则可能会损害数据的局部性。

除此之外,堆栈分配非常便宜,而且比堆分配更快。在某些编译器(如MSVC)上,使用超过4k的堆栈会使编译器生成缓冲区安全检查。(但是它可以被禁用。)

https://github.com/kennethlaskoski/SubtleBug

这段代码包含一个我称之为微妙的错误,因为二进制文件在iOS模拟器上完美运行,在真实设备上可耻地崩溃。前面的剧透:实际设备上发生的是由于分配了一个非常大的变量而导致的经典堆栈溢出。模拟器使用了更大的x86堆栈,所以一切都很顺利。http://en.wikipedia.org/wiki/Stack_overflow#Very_large_stack_variables

堆栈溢出问题应该是您主要关心的技术问题,但如果其他人要使用此代码,请仔细考虑1500的神奇大小是否会干扰他人对该函数的使用。