【问题标题】:What is activation record in the context of C and C++?什么是 C 和 C++ 上下文中的激活记录?
【发布时间】:2010-11-18 23:16:36
【问题描述】:

这对 C/C++ 程序员来说意味着什么以及了解它有多重要?

至少在概念上,跨平台是否相同?

我把它理解为一个分配的内存块,用于存储函数的局部变量...

我想知道更多

【问题讨论】:

  • @Neil,你的评论应该是答案。
  • 当你有太多的问题时,它们会生成一个非常酷的关于编程问题的网站。
  • 实际上,他没有,但我不喜欢发布仅包含维基百科链接的答案。
  • 函数调用的帧不需要在栈中实现。 ISO C 和 ISO C++ 都没有提到“堆栈”,除了 ISO C++ 第 15 条中的“堆栈展开”,它基本上是“自动对象的 LIFO 销毁”,除了实现细节之外什么都没有做。实际上允许从堆或其他内存区域分配调用堆栈,而不是 ISA 特定的堆栈。

标签: c++ c


【解决方案1】:

激活记录 并不是一个在谈论 C 或 C++ 语言本身时经常使用的概念。 激活记录的格式在很大程度上是特定于平台的。

从概念上讲,如何传递参数、局部变量的生命周期、函数返回的位置以及调用堆栈如何展开以响应期望抛出都是 C++ 的重要部分,并且(后一个 C 除外)。这些如何实现的细节将影响激活记录在特定平台上的样子,但在用 C++ 或 C 编写代码时通常不需要了解这一点。

【讨论】:

    【解决方案2】:

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

    • 被调用者的本地人
    • 返回地址给调用者
    • 被调用者参数
    • 上一个堆栈指针 (SP) 值

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

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

    对于 C/C++ 程序员,此结构的一般知识有助于理解某些实现功能,例如调用约定,甚至为什么缓冲区溢出允许运行第 3 方恶意代码。

    深入的知识将进一步加深上述概念,并允许程序员在没有调试器或调试符号的情况下调试他们的应用程序并读取内存转储。

    不过,更一般地说,C/C++ 程序员可以在其业余编程生涯的大部分时间里,甚至无需考虑调用堆栈。

    【讨论】:

    • @Alexandre Bell 我从您提到的内容中了解到,AR(堆栈帧)包含本地变量、ret 地址和参数。我的问题是:被调用函数的代码存储在哪里?
    • @FernandoGabrieli C 中有不同的段,如代码段、堆栈段、堆段。因此功能代码将存储在代码段中。参考this
    【解决方案3】:

    激活记录包含以下三样东西

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

    【讨论】:

      【解决方案4】:

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

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

      您可能想知道“有什么例子吗?”。

      • 当然,看看IBM mainframes' stackless designstack是不可用的,它的activation recordheap-based
      • 对面,也有不提供heap的平台(又名heap-less),例如Arduino(但也表示 new 关键字和 new-expression 不能使用)。
      • 除了硬件限制外,一些函数式语言不能将局部变量存储在上,所以它们的激活记录分配在堆上,如果您想知道原因,here 是一个很好的参考。

      就像@FrakHB 说的,不只是heapstack,其他regions的内存也可以是activation record strong>,这就是具体实现的意思。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-31
        • 2011-06-17
        • 2011-09-13
        • 1970-01-01
        • 2017-05-27
        • 2020-03-06
        • 2012-01-17
        • 1970-01-01
        相关资源
        最近更新 更多