“在编译时就知道堆栈上分配的所有内存”是什么意思?

mar*_*zzz 5 c++ stack allocation compilation

阅读这篇有关堆栈与堆的精彩教程时,我对这句话有疑问:堆栈上分配的所有内存在编译时都是已知的

我的意思是,如果我处于一个for取决于用户输入(i从 0 到 X)的周期内,并且for在堆栈上分配内存(例如创建某些类的新实例并放入类容器内),那么它不知道编译程序时堆栈将如何增长(它错过了用户的输入)。

我误解了什么吗?

Sme*_*eey 4

对于读者来说,所做的陈述有点简化。您是对的,堆栈本质上是动态的,实际分配的数量可能会根据动态输入而变化。这是一个带有递归函数的简单示例:

void f(int n)
{
    int x = n * 10;
    if(x == 0) return;

    std::cout << x << std::endl;
    f(n - 1);
}

int main()
{
    int n;
    std::cout << "Enter n: " << std::endl;
    std::cin >> n;
    f(n);
}
Run Code Online (Sandbox Code Playgroud)

这里显然,递归函数 的调用次数f取决于n用户输入的内容,因此对于任何给定的实例,编译器不可能知道x中局部变量的确切内存地址f。但是,它确实知道的是x与本地堆栈帧的偏移量,我相信该示例所指的就是该偏移量。堆栈帧是每次函数调用发生时准备的堆栈局部区域。在给定的堆栈帧内,局部变量的位置实际上是相对于堆栈帧开头的已知常量偏移量。这个“开始”在每次调用中都保存在标准寄存器中,因此编译器要找到任何本地地址所要做的就是将其固定的已知偏移量应用于这个动态“基指针”。

  • 因此,在编译时已知的是每个“堆栈帧”的大小。但不知道会有多少个堆栈帧。你是说这个吗? (3认同)
  • 正是如此。特定堆栈帧内变量的查找采用“BP - x”的形式,其中“BP”是表示该帧的“基指针”的寄存器(在编译时未知),“x”是编译时的指针。 - 相关变量的时间常数(例如“BP - 8”)。之所以存在“-”符号是因为堆栈向下增长,远离基指针 (3认同)