使用GOTO时StackFrames如何受影响?

时间:2017-05-16 09:51:25

标签: c function memory operating-system stack

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

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

他还在下面提出了一些问题

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

以下是我尝试回答上述问题

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

如果函数彼此独立,那么只有main函数或main函数和调用函数将在堆栈中

  

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

我认为这是不可能的,因为这可能会破坏记忆

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

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

1 个答案:

答案 0 :(得分:4)

  

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

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

  

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

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

  

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

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

  

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

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

当"非本地转到"通过setjmp / longjmp,normal" stack unwinding"执行没有发生。因此,任何所需的清理操作都不会发生。

来自C的

longjmp()函数(参见Wikipedia entry for setjmp.h的基础知识)。 longjmp()将堆栈向下跳转到相应的setjmp(),跨越尽可能多的堆栈帧。与我们将看到的其他方法不同,longjmp()不会遍历帧列表,它只是一次性地通过它们全部爆炸肆意忽略它们可能包含的任何珍贵或美丽的东西。 / p>

详细了解here

longjmp()会将堆栈返回到之前使用setjmp()保存的状态。如果中间的任何框架被移除,那么下面的所有框架也是如此;即没有"洞"正如Klas所提到的那样,在longjmp之后的堆栈中。