调用堆栈和堆栈有什么区别?

Nik*_*ili 5 c++ memory stack callstack heap-memory

我想我可能问了一个非常错误的问题,但我确实尝试通过谷歌搜索来理解它,但没有运气。

众所周知,我们有栈和堆。动态分配的堆,局部变量的栈等

假设我有以下 C++ 代码。

void bla(int v1, int v2, int v3) {
    int g = v1 + v2+ v3;
}

void nice(int g){
    int z = 20;
    int k = 30;
    bla(g, z, k);
}

int main(){
    cout<<"Hello World";
    nice(40);
}
Run Code Online (Sandbox Code Playgroud)

现在,让我们想象有一个堆栈。据我所知,例如值z,k,g将存储在堆栈中。但是当我调用调用的函数时,这些nice存储bla在哪里?我读到每个函数执行都会导致调用堆栈大小增加 1。我想说,即使创建局部变量也会导致调用堆栈增加 1。

那么,那些( callstack, stack) 到底有什么关系呢?

这是我的假设:

当我们调用 时,就会创建nice全新的。stack在那里,我们存储z and k. 当nice调用时bla,现在stack会创建另一个堆栈bla并存储第二个堆栈v1,v2,v3,g。等等。每个函数都需要自己的callstack,但我们stack也可以调用它。

Laj*_*pad 1

堆栈表示由一组通常相似的项组成的数据结构,并具有以下功能:

  • push:将一个项目添加到堆栈的“顶部”,该项目将成为新的顶部
  • pop:从顶部删除项目,因此之前位于顶部的项目将再次成为顶部;此操作返回您删除的项目
  • top:获取堆栈顶部的项目,而不修改堆栈

您的内存有一个称为“堆栈”的部分,正如您正确理解的那样,函数存储在其中。那就是调用堆栈。但是,堆栈和调用堆栈并不是 100% 等效,因为堆栈在许多其他情况下都会使用,基本上是在需要 LIFO(后进先出)处理时使用。例如,它用于 CPU 的 LIFO 策略,或者当您在图中进行深度优先搜索时。简而言之,堆栈是一种数据结构,可以在很多情况下应用,内存中的调用堆栈就是一个突出的例子。

那么,为什么使用堆栈来在内存中存储函数调用。让我们考虑嵌入式函数调用,例如:

f1(f2(...(fn(x))...))

根据经验,为了计算 fi,1 <= i < n,您需要计算 fj,其中 1 < j <= n,假设 i < j。因此,f1 是第一个被调用的,但最后一个被求值的。因此,您有一个 LIFO 处理,最好通过使用堆栈来完成。