我参加了一个集会课,我们正在学习堆栈。从我所学到的东西中,最终必须弹出所有被推入堆栈的东西(清理堆栈)。为什么我们绝对需要清理堆栈?我读过它是为了防止内存泄漏,是吗?
非常感谢
答案 0 :(得分:3)
给定的执行线程只有一定数量的堆栈。
其目的是暂时保存调用函数时所需的数据(例如返回地址和传递给函数的参数)。
如果在函数退出时不清理堆栈,最终会耗尽堆栈空间。
此外,作为超出堆栈的一般规则,程序使用的任何资源(堆栈空间,堆空间,文件句柄等)都应保持最短的时间,以提高整体效率。 / p>
答案 1 :(得分:2)
堆栈是一个有限数量的内存,就像任何内存分配系统一样,如果你从不清理它,它只会增长和增长。最终你会溢出堆栈,当你覆盖其他内存区域或者只是生成一个无效的地址时,所有的地狱都会崩溃。
答案 2 :(得分:2)
如果你没有清理堆栈,调用函数将如何找到它的变量?被调用者将运行,在堆栈上使用自己的变量执行某些操作,然后返回调用者 - 现在如果堆栈指针已更改,调用者可以做什么?如何恢复它以找出它自己的堆栈变量在哪里?唯一的答案是清理堆栈 - 无论是谁(被叫者或来电者)都没关系,但某人必须这样做。
术语“内存泄漏”通常是指丢失指向动态内存分配的指针,因此您无法free()
分配。
答案 3 :(得分:2)
除了其他答案之外,我使用的大部分处理器都将函数调用的返回地址放在堆栈上。
RET / RTS(或任何返回语法,如果用于您的处理器)只需从堆栈中提取返回地址,并将PC,ProgramCounter设置为该地址。
如果函数在堆栈上放置了其他变量但没有删除它们,那么RET将返回错误的值并返回错误的地址,从而导致各种奇怪的行为和/或异常/陷阱。
由此类行为引起的故障可能变得非常难以调试,尤其是如果它们没有发生故障immediatley
答案 4 :(得分:1)
软件例程(函数)可以共享堆栈以获取调用参数并返回变量以及记住调用者的返回地址。
由于汇编中的堆栈指针通常是寄存器,因此它是一种全局变量。如果在函数结束时,堆栈指针未设置到正确的位置(“堆栈清理”),可能会发生许多不好的事情。系统可以返回错误的地址,调用者可能会弹出错误的返回值,可能会出现堆栈溢出,下溢等。
答案 5 :(得分:1)
每个函数都可以使用堆栈,即使有些你不会在你的程序中嵌入函数调用one()调用two()两个调用three()等。
因此,如果函数一在堆栈上有局部变量A,B,C,则它调用两个,两个有两个变量,它在堆栈上使用E和F.然后三个在堆栈上有G和H.如果你没有将堆栈指针恢复到三个输入时的位置,当你返回到两个时,它会认为它正在访问E和F,而是访问G和H或其他东西,具体取决于三个堆栈框架()函数。
你不会因内存泄漏而崩溃。有时你很幸运并且幸存下来,这可能是这些函数的代码的本质,但一般来说它会导致你编译的代码用于调用你失败的更高级别的函数。
现在是内存泄漏就像一样,一个功能正在捣毁别人的ram,当然。
如果处理器使用堆栈作为返回值,那只会使情况变得更糟,崩溃或奇怪的行为更有保障,更糟糕。