有人可以建议我任何练习或代码来帮助我更好地理解堆和堆栈内存吗?我在教科书中读过很多,只是想看一些代码来更好地理解。也许一些堆栈溢出示例或类似的东西。我认为 C/C++ 将是一个理想的候选人。
1 回答
堆栈和堆都驻留在内存中。确切的位置不一定重要,但您应该设法了解它们的数据结构。
堆:
对于堆,您应该阅读这个示例实现,malloc
它应该让您了解它是如何工作的(包括代码)。
堆栈(理论):
堆栈(基本数据结构)是一个相当容易理解的概念,这里解释得很好。该链接还简要介绍了它在您的程序中的使用方式。我还没有找到我认为可以很好地描述它的东西,因此我将包括以下内容作为后续参考:
如果这些解释不完全正确,您应该尝试找到以您可以理解的方式解释调用堆栈和堆栈框架的内容。
堆栈(代码):
我指出的所有链接都解释了理论并且没有给你代码。在学习了计算机体系结构和汇编语言之后,我对堆栈的理解有了很大的提高。
因此,如果您想要一个代码示例,您应该尝试实现一个简单的汇编函数并将其链接到 C 程序。这是一个示例(简要介绍了汇编)。
Java 和 C++:
Java 和 C++ 对你隐藏了这些东西,所以如果这是一个学习练习,我推荐 C 和汇编。我不确定是否可以在 Java 中做到这一点。你可以在 C++ 中,但它变得复杂......
我对调用堆栈的解释:
我将尝试对 C 编程语言和汇编的调用堆栈和堆栈框架进行简短的解释。
为此,让我们定义一个简单的机器,以便我们可以从同一页面开始。
我们的处理器有有限数量的寄存器,比如说 8 个。像加法、减法、比较和其他操作只能在寄存器上完成。您只能在内存上执行两条指令,它们是load和store。这些指令分别从内存复制到寄存器,或从寄存器复制到内存。
现在,如果我们想添加 2 个数字,我们有很多变量。我们将一个数字加载到寄存器 1 中,另一个加载到寄存器 2 中,将它们相加并将结果放入寄存器 3。现在,如果我们对寄存器 4 和 5 进行另一操作,将结果存储在寄存器 6 中,然后想要添加寄存器7 和 8 我们把结果放在哪里?我们已经用完了变量...
显然,当我们不处理它时,我们需要使用内存并将信息保存在那里。为此,我们需要知道每个变量在内存中的位置。
您可以记住每个变量的地址并每次手动输入它们,可能会将其写在办公桌上一张纸上的合理名称旁边。但这将是乏味的,并且会对功能造成严重的限制。
函数具有局部变量。如果这些变量的地址是硬连线的,它们将总是被分配给函数,并且会给递归带来很大的问题。如果一个函数要调用自己,它将覆盖它的调用者(自己)正在使用的值。
要解决这个问题,最简单的方法是使用堆栈。但是,为此我们需要将堆栈指针地址保存在某个地方。所以让我们同意从现在开始我们将使用寄存器 8 作为我们的堆栈指针。
还可以说,当您将内容压入堆栈时,我们将从堆栈指针中减去我们想要的字节数,当我们想要弹出时,我们会将字节数添加到堆栈指针中。
每次调用函数时,我们都会将其局部变量放入堆栈。既然我们知道我们想要什么变量,我们就知道我们需要多少内存。
但是要访问每个局部变量,我们需要知道它的地址……让我们建立一个例子。
假设我们有 2 个变量,这两个变量在我们的函数中都有 2 个字节,并且堆栈指针是 18。
根据我们的协议,让堆栈指针减去 4 个字节,使堆栈指针等于 14。
现在要访问第一个变量,我们将简单地使用堆栈指针。要访问第二个,我们将从堆栈指针中减去 2。
只要我们的函数正在运行,这将是正确的,但在我们的函数退出之前,我们将通过再次向其添加 4 来释放堆栈中的局部变量,使堆栈指针变为 18(就像我们开始之前一样)。