C中的递归堆栈

时间:2015-06-26 05:53:09

标签: c recursion linked-list stack

在递归过程中,会创建一个堆栈,该堆栈包含该堆栈,包含值还是存储操作数的地址

void recursiveReverse(struct node** head_ref)
{
   struct node* first;
   struct node* rest;

   /* empty list */
   if (*head_ref == NULL)
      return;   

   /* suppose first = {1, 2, 3}, rest = {2, 3} */
   first = *head_ref;  
   rest  = first->next;

   /* List has only one node */
   if (rest == NULL)
      return;   

   /* reverse the rest list and put the first element at the end */
   recursiveReverse(&rest);
   first->next->next  = first;  

   /* tricky step -- see the diagram */
   first->next  = NULL;          

   /* fix the head pointer */
   *head_ref = rest;                 
}

在上面的代码中,当第一个指针继续改变时,其余指针保持最后一个节点的地址,即它从堆栈中获取值,而不是指针。 所以首先我想了解递归堆栈,它的结构,它包含的内容,它是如何工作的以及对上述代码的解释表示赞赏

1 个答案:

答案 0 :(得分:1)

  

我想知道递归堆栈,它的结构,它包含的内容,它是如何工作的

递归函数与任何其他函数完全相似。因此,对于递归函数的即时调用,它将像正常函数一样维护堆栈。每次函数声明一个新变量时,它都会被推送到堆栈上。然后每次函数退出时,该函数推送到堆栈的所有变量都被释放(也就是说,它们被删除)。一旦释放了堆栈变量,该内存区域就可用于其他堆栈变量。

因此,当调用递归函数时,其所有变量都被推送到堆栈上,当它返回时,堆栈变量被释放。请注意,自动局部变量被分配为单个块,并且堆栈指针的前进足够远,以便考虑它们的大小总和。

长话短说,每次调用递归函数都会占用堆栈中的内存块。请看下面的C中的无限递归示例。

int foo() 
{
     int someVariable;
     return foo();
}

函数foo在被调用时会继续调用自身,每次在堆栈上分配一块额外的空间,直到堆栈溢出导致分段错误。

如需了解更多信息,请按以下方式声明foo()

int foo() 
{
    double x[1024];
    return foo();
} 

然后,每个递归调用,1024 * sizeof(double)的额外内存将在堆栈中分配给x。但是使用malloc()将分配内存而不是堆栈

最后,每次调用递归函数(包括返回值)时,返回地址也会被压入堆栈。

如您所见,每个递归调用都会推送一个新的堆栈帧,如果递归无法达到基本情况,堆栈将很快耗尽并导致堆栈溢出。

参考:Stack based memory allocationStack overflowMemory Stack vs Heap