数组声明:Global Vs Local

时间:2015-07-31 15:50:39

标签: arrays global local

为什么我们不能在主函数内部或在本地内部的任何函数内声明一个10000000整数(或者说足够大)的数组,而它可能是全局的?

2 个答案:

答案 0 :(得分:4)

tl; dr:局部变量的空间有限。这就是CPU和操作系统的工作方式。

这是许多语言和实现共享的实现细节,例如典型桌面操作系统上的C,C ++。

运行代码的大多数平台都会留出一些称为 Stack 的内存,用于返回地址和本地存储。这只是CPU(Intel,AMD等)如何执行机器代码的细节。

堆栈的分配速度非常快,但内存只有在函数调用返回后才有效。这使其成为C / C ++局部变量的理想选择。

但是,堆栈空间有限,因此大的分配将失败 堆栈溢出 - 即使“其他地方”仍有足够的内存。

程序启动时会分配全局变量的内存。例如。可执行文件将指示“我需要这么多空间填充零,我需要这么多空间来存储数据,并且需要很多代码空间。”

“第三个”内存位置是:它用于分配有malloc / new等的内存。堆上的分配比在堆叠(并且有更多的问题需要处理),并且它们会一直存在,直到你释放它们,这既好又负担。

有些附注,故意遗漏,因为它与问题没有直接关系:

Stack只是一系列(contiguos)内存,您只能从顶部分配和释放内存。这使它有限,方便和快速。

在现代桌面系统上,32位进程通常不再耗尽内存,但是超出地址空间:仍有可用的物理内存,但32位字中所有可用的可用地址都用完了。

每个执行线程都有自己的堆栈,而全局变量和堆在进程的所有线程之间共享。

为什么编译器不会在其他地方移动大量分配?

首先,“它一直都是这样”。许多现有代码可能巧妙地依赖于旧行为,并且“改进”编译器可能会破坏此代码。

其次,由于各种原因,唯一通常适合“其他地方”的是堆。堆栈和堆分配之间的性能差异非常显着:

  • 堆分配更贵
  • 堆是共享的,因此必须同步从多个线程访问堆,这可能非常昂贵。
  • 堆栈的顶部几乎总是在CPU的缓存中(因为非常频繁地访问该地址范围)。堆很可能不是

大多数情况下,这些细节并不重要,但对于某些操作,这种差异很大。如果编译器决定在堆上放置一些分配,我们就会失去可预测性。

答案 1 :(得分:0)

(编辑:全局变量通常不会进入堆中)

这可能是由于可用的堆栈内存与总内存之间存在差异。局部变量放在堆栈上,而全局变量放在静态分配的内存段中。以下是一个更一般的问题,它有一个很好的答案,概述了程序内存分配:

Global memory management in C++ in stack or heap?