【问题标题】:How StackFrames are impacted when GOTO is used?使用 GOTO 对 StackFrames 有何影响?
【发布时间】:2017-10-15 08:04:12
【问题描述】:

我正在关注Memory Layout And The Stack 以了解堆栈帧..

作者很好地解释了堆栈帧,并说明了在给定时间点堆栈中的内容

他还在下面问了一些问题

  • 假设一个程序进行了 5 次函数调用。堆栈上应该有多少帧?
  • 我们看到堆栈线性向下增长,当函数返回时,堆栈上的最后一帧被释放并返回到未使用的内存中。是否有可能将堆栈中间某处的帧返回到未使用的内存?如果是这样,这对正在运行的程序意味着什么?
  • goto() 语句能否导致堆栈中间的帧被释放?答案是否定的,但为什么呢?
  • longjmp() 能否导致堆栈中间的帧被释放?

以下是我对以上问题的回答

  • 假设一个程序进行了 5 次函数调用。堆栈上应该有多少帧?

如果函数相互独立,则只有主函数或主函数和调用函数在堆栈中

我们看到堆栈线性向下增长,当函数返回时,堆栈上的最后一帧被释放并返回到未使用的内存中。是否有可能将堆栈中间某处的帧返回到未使用的内存?如果是这样,这对正在运行的程序意味着什么?

我认为这是不可能的,因为这可能会破坏内存

我不确定其余的问题。请您帮忙解决这个问题

如果您需要更多信息,请告诉我

【问题讨论】:

  • 是否有可能将堆栈中间某处的帧返回到未使用的内存中?:不,它是stack

标签: c function memory operating-system stack


【解决方案1】:

假设一个程序进行了 5 次函数调用。堆栈上应该有多少帧?

最多 6 个(假设在调用所有函数之前没有函数返回)。一个用于main(),一个用于每个函数调用。

我们看到堆栈线性向下增长,当函数返回时,堆栈上的最后一帧被释放并返回到未使用的内存中。是否有可能将堆栈中间某处的帧返回到未使用的内存?如果是这样,这对正在运行的程序意味着什么?

不,因为堆栈是不允许随机访问删除的。您只能从堆栈中弹出。

goto() 语句能否导致堆栈中间的帧被释放?答案是否定的,但为什么?

因为它会改变堆栈展开。使用 goto 退出代码块不会展开堆栈,这是您应该(几乎)从不使用 goto 的原因之一。在What is stack unwinding? 中阅读更多信息但是,请注意这是与 C++ 相关的,在 C 中 goto out of block 是明确定义的,正如 Antti 所提到的。

longjmp() 能否导致堆栈中间的帧被释放?

我认为是的,因为这是一个空间案例。但这与我的第二个答案有点矛盾。

当通过 setjmp/longjmp 执行“非本地 goto”时,不会发生正常的“堆栈展开”。因此也不会发生任何必需的清理操作。

longjmp() 来自 C 的函数(请参阅 Wikipedia entry for setjmp.h 了解基础知识)。 longjmp() 向下跳到堆栈 到相应的 setjmp(),其间的堆栈帧数一样多。与我们将看到的其他方法不同,longjmp() 不会遍历帧列表,它只是一次将它们全部爆破,肆意无视它们可能包含的任何珍贵或美丽的东西。

阅读更多关于它的信息here

longjmp() 将堆栈返回到之前使用setjmp() 保存的状态。如果中间的任何帧被删除,那么下面的所有帧也会被删除;也就是说,正如 Klas 所提到的,longjmp 之后的堆栈中不会有“漏洞”。

【讨论】:

  • 非常感谢您的宝贵时间和帮助
  • OP 询问的是 C 而不是 C++。在 C goto 中,块外是明确定义的。
  • @KlasLindbäck 很棒的评论,复制粘贴在答案中。如果这对您来说有问题,请告诉我,我会修改它!安蒂,准确,谢谢!
猜你喜欢
  • 2012-05-10
  • 2015-01-05
  • 2011-10-26
  • 2023-03-12
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多