C 如何仅在编译时确定堆栈区域中的内存量?

C 如何仅在编译时确定堆栈区域中的内存量?,c,C,激活记录在堆栈中创建。这些都是在程序运行期间创建和销毁的,也就是说,堆栈区域在程序运行期间会改变其大小 即使堆栈区域中的内存是在运行时创建的,但内存量(激活记录大小)是在编译时确定的 我不理解这样一个概念,即当在运行时创建堆栈区域中的内存时,如何在编译时确定激活记录的大小?当操作系统启动一个进程时,它会为该进程分配固定数量的空间,而不是用作堆栈。当函数开始或结束时,不会创建或销毁内存。它是从堆栈顶部借用的,堆栈上未使用的任何内容 当一个函数被调用时,它会抓住堆栈空间的一个夹头(在堆栈的顶部),它

激活记录在堆栈中创建。这些都是在程序运行期间创建和销毁的,也就是说,堆栈区域在程序运行期间会改变其大小

即使堆栈区域中的内存是在运行时创建的,但内存量(激活记录大小)是在编译时确定的


我不理解这样一个概念,即当在运行时创建堆栈区域中的内存时,如何在编译时确定激活记录的大小?

当操作系统启动一个进程时,它会为该进程分配固定数量的空间,而不是用作堆栈。当函数开始或结束时,不会创建或销毁内存。它是从堆栈顶部借用的,堆栈上未使用的任何内容

当一个函数被调用时,它会抓住堆栈空间的一个夹头(在堆栈的顶部),它将使用它自己(作为变量)。编译器可以扫描一个函数并提前计算所有这些,因为它不需要允许对每个函数进行函数调用——它们都是独立处理的

当函数存在时,它释放堆栈空间(只需将堆栈指针调整回原来的位置)并返回给调用方

由于调用的每个函数都有自己的保留空间,并且没有堆栈顶部的空间,因此编译器不需要允许在其他函数中调用的函数使用堆栈空间。每个函数始终从堆栈的现有顶部(可用空间所在的位置)开始工作


Malloc()使用堆内存,它与堆栈分开。只有局部变量使用堆栈。有一个名为alloca()的不安全函数也使用堆栈,但通常不使用堆栈,因为无法依靠它返回有效指针。

对于给定的操作系统/操作环境,堆栈量通常是固定的。如果你用记录溢出堆栈,你的程序就会崩溃。每次调用函数时,它都需要一些堆栈空间,以便分配空间——激活记录。编译时已知给定过程的激活记录有多大(多多少少;可变长度数组会使事情复杂化),但不知道总共需要多少空间,因为函数调用的顺序未知-尤其是递归等。一般来说,在程序运行期间,堆栈区域的大小不会改变。这就是为什么可以在不耗尽机器内存的情况下发生堆栈溢出。运行时的变化是堆栈中有多少正在使用,而有多少可用、未使用。我不确定我是否理解这个问题。如果是关于编译器如何确定所需的堆栈大小,那么它就不能,编译器(或者更像链接器)只使用一些预定义的大小,希望它足够了。如果是关于为什么没有实现堆栈增长,那么我想没有人真的认为有必要这样做,特别是如果这个操作不是免费的。每个线程的堆栈大小是固定的,通常是用链接器参数设置的,或者它有一个默认值。这个答案可能与某些操作系统有关,但不是全部。建议列出您正在编写的操作系统。这是调用框架堆栈使用的概述。这是为了澄清我认为是什么混淆了海报,我认为这与函数调用函数有关。它并不打算作为任何特定操作系统中堆栈使用情况的最终描述。这真的会把OP搞糊涂,对这个问题视而不见。如果您觉得有必要深入了解这些细节,那么您可以自由地自己更全面地回答。我们通常说,堆栈向下增长,而堆向上增长,那么堆栈大小如何仅在编译时保持固定,仍然很困惑,请澄清这一点,我认为您在这里关注的是编译时间。某些系统上的堆栈大小可能会发生变化,编译器所做的只是遵循生成代码时如何使用堆栈的规范。确切地说,这意味着系统特定。堆和堆栈通常不应被视为是连接的。堆不一定会增长。堆的一部分由应用程序在malloc()时分配(借用),但堆是否允许增长取决于操作系统。