为什么我们不能在主函数内部或在本地内部的任何函数内声明一个10000000整数(或者说足够大)的数组,而它可能是全局的?
答案 0 :(得分:4)
tl; dr:局部变量的空间有限。这就是CPU和操作系统的工作方式。
这是许多语言和实现共享的实现细节,例如典型桌面操作系统上的C,C ++。
运行代码的大多数平台都会留出一些称为 Stack 的内存,用于返回地址和本地存储。这只是CPU(Intel,AMD等)如何执行机器代码的细节。
堆栈的分配速度非常快,但内存只有在函数调用返回后才有效。这使其成为C / C ++局部变量的理想选择。
但是,堆栈空间有限,因此大的分配将失败 堆栈溢出 - 即使“其他地方”仍有足够的内存。
程序启动时会分配全局变量的内存。例如。可执行文件将指示“我需要这么多空间填充零,我需要这么多空间来存储数据,并且需要很多代码空间。”
“第三个”内存位置是堆:它用于分配有malloc
/ new
等的内存。堆上的分配比在堆叠(并且有更多的问题需要处理),并且它们会一直存在,直到你释放它们,这既好又负担。
有些附注,故意遗漏,因为它与问题没有直接关系:
Stack只是一系列(contiguos)内存,您只能从顶部分配和释放内存。这使它有限,方便和快速。
在现代桌面系统上,32位进程通常不再耗尽内存,但是超出地址空间:仍有可用的物理内存,但32位字中所有可用的可用地址都用完了。
每个执行线程都有自己的堆栈,而全局变量和堆在进程的所有线程之间共享。
为什么编译器不会在其他地方移动大量分配?
首先,“它一直都是这样”。许多现有代码可能巧妙地依赖于旧行为,并且“改进”编译器可能会破坏此代码。
其次,由于各种原因,唯一通常适合“其他地方”的是堆。堆栈和堆分配之间的性能差异非常显着:
大多数情况下,这些细节并不重要,但对于某些操作,这种差异很大。如果编译器决定在堆上放置一些分配,我们就会失去可预测性。
答案 1 :(得分:0)
(编辑:全局变量通常不会进入堆中)
这可能是由于可用的堆栈内存与总内存之间存在差异。局部变量放在堆栈上,而全局变量放在静态分配的内存段中。以下是一个更一般的问题,它有一个很好的答案,概述了程序内存分配: