什么是C和C ++上下文中的激活记录?

对于C / C ++程序员来说,它是什么意思以及了解它有多重要?

它在整个平台上是否相同,至少在概念上是这样?

我把它理解为用于通过函数存储局部变量的已分配内存块…

我想了解更多

激活记录是Stack Frame的另一个名称。 它是组成调用堆栈的数据结构。 它通常由以下部分组成:

  • 被叫者的当地人
  • 将地址返回给调用者
  • 被调用者的参数

因此,调用堆栈由任意数量的激活记录组成,这些激活记录在添加新的子例程时被添加到堆栈中,并在它们返回时从堆栈中移除(通常)。

元素的实际结构和顺序是平台甚至实现定义。

对于C / C ++程序员,这种结构的一般知识对于理解某些实现function(如调用约定)以及为什么缓冲区溢出允许运行第三方恶意代码很有用。

更加亲密的知识将进一步推动上述概念,并允许程序员调试其应用程序并读取内存转储,即使没有调试器或调试符号也是如此。

更一般地说,一个C / C ++程序员可以通过他们的业余爱好者编程生涯的很大一部分,甚至没有考虑调用堆栈。

激活记录不是一个在谈论C或C ++语言本身时使用的概念。 激活记录的格式非常具体。

从概念上讲,参数的传递方式,局部变量的生命周期,函数返回的位置以及调用堆栈如何响应推测投掷都是C ++的重要组成部分(后者除外)。 这些实现方式的细节将影响特定平台的激活记录 ,但在C ++或C中编写代码通常不需要了解这一点。

当我们调用函数时,我们需要一个地方来存储调用者和被调用者的上下文,这个地方叫做激活记录 (AKA stack frame )。

是的, 激活记录组成了调用堆栈 ,但这并不意味着激活记录必须基于堆栈。 它是特定于实现的

你可能想知道“任何例子?”。

  • 当然,只需看看IBM大型机的无堆栈 设计 , 堆栈不可用,其激活记录基于堆的
  • 相反,还有一个平台不提供 (AKA无 ),例如Arduino (但它也意味着不能使用关键字和new-expression )。
  • 除了硬件限制外,一些函数式语言不能在堆栈上存储局部变量 ,因此它们的激活记录堆上分配,如果你想知道原因, 这里是一个很好的参考。

就像@FrakHB所说的那样,不仅堆栈 ,其他内存区域也可以是激活记录 ,这就是具体实现方式。

激活记录包含以下三件事

1.function定义
2.可变定义
3.function应用(函数调用)