Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 递归函数的内存分配_C++_C_Memory_Memory Management_Recursion - Fatal编程技术网

C++ 递归函数的内存分配

C++ 递归函数的内存分配,c++,c,memory,memory-management,recursion,C++,C,Memory,Memory Management,Recursion,调用递归函数时如何分配内存? 函数有自己分配的内存。调用时,参数(不是引用传递的参数)和变量将获得内存。因此,当从函数体内部再次调用函数时,如何将内存分配给第二次调用的变量和参数?递归调用函数就像调用其他函数一样。因此,内存的分配方式将与调用任何常规函数的方式相同。这与调用任何其他函数的方式相同。变量(不是引用传递的变量)在堆栈上分配。当函数开始返回时(即达到基本情况),堆栈将按照每次嵌套递归调用时它被推送到堆栈的顺序弹出 这段youtube视频非常好地解释了递归函数的调用堆栈:当一个函数(如果

调用递归函数时如何分配内存?
函数有自己分配的内存。调用时,参数(不是引用传递的参数)和变量将获得内存。因此,当从函数体内部再次调用函数时,如何将内存分配给第二次调用的变量和参数?

递归调用函数就像调用其他函数一样。因此,内存的分配方式将与调用任何常规函数的方式相同。

这与调用任何其他函数的方式相同。变量(不是引用传递的变量)在堆栈上分配。当函数开始返回时(即达到基本情况),堆栈将按照每次嵌套递归调用时它被推送到堆栈的顺序弹出

这段youtube视频非常好地解释了递归函数的调用堆栈:

当一个函数(如果
func1
)调用另一个函数(调用它
func2
)时,执行
func2
所需的数据被推送到堆栈上。对于递归函数,这一点不变(当
func2
func1
相同时)


如果递归函数被递归调用
10次
,则会有
10个
堆栈帧,每个帧对应于函数的一次调用。

调用函数时,必要的参数会被推到堆栈上。当函数完成其任务时,参数弹出,程序计数器恢复


递归函数也不例外。

函数参数和局部变量在堆栈上分配。它们形成了一个所谓的。当递归调用函数时,会为函数的每个递归调用分配一个堆栈帧

例如,如果void f()被递归调用三次

// Assume stack grows upwards
stack frame #3 <== the most recent call
stack frame #2
stack frame #1
//假设堆栈向上增长

自动变量的堆栈帧#3内存分配在上。当您调用另一个函数(递归地self或其他函数)时,堆栈帧到目前为止仍保持其状态,我们在堆栈上分配更多内存(我们这样说)来存放这个新函数的局部变量。当函数结束时,新的堆栈帧将被丢弃,我们将恢复到上一个(calee)堆栈帧


您可以使用您选择的任何调试器来更好地理解事物。如果您不理解某些内容,请询问。

重复使用堆栈内存来执行

浏览下面的例子

void rev(Node* head){
if(head==NULL) return;
head=head->next;
rev(head);
cout<<head->data<<endl;}

希望这会对您有所帮助。

递归函数与任何其他函数没有什么不同——自动局部变量是作为单个块分配的,方法是将堆栈指针向前移动足够远,以说明它们的大小之和(加上对齐所需的任何填充)


每个递归调用都以这种方式推送一个新的堆栈帧,然后在返回时弹出它。如果递归无法达到基本情况,堆栈将迅速耗尽,导致同名堆栈溢出崩溃。

使用后需要释放内存

下面是一个示例程序,说明了这一点

您编写的函数(代码行)存储在文本段中,调用时在堆栈内存中分配一个帧,变量(静态除外)的内存也在给定帧的堆栈中分配


递归函数和它的普通函数没有什么不同,它被调用n次。因此,它的内存(帧)也在堆栈上分配了n次

调用函数时,它的参数以及其他函数状态都保存在堆栈上

函数调用期间构造的堆栈帧包含以下内容:

  • 函数参数
  • 函数的返回地址
  • 帧指针
  • 异常处理程序框架
  • 局部声明的变量
  • 缓冲区
  • 被叫方保存寄存器

C++不保证自动管理的内存将以堆栈式结构分配。我认为使用递归函数时这是事实。“为什么不在这种情况下呢?”凯撒:虽然C++标准不使用“堆栈”这个词,但是“自动存储持续时间”和每个主要处理器指令集架构(ISA)的机制都是特定的语义。但是,C++并不能保证自动管理的内存将被分配到一个类似堆栈的结构上。就像我所说的,递归函数就像任何其他函数一样被处理,这些函数在堆栈上被分配。如果您查看部件,将执行一个
&
弹出
操作。只能放在堆栈上。顺便说一下,“自动管理内存”是什么意思?虽然大多数自动管理的内存是用堆栈来处理的,但是C++并不能保证所有的系统都必须使用堆栈来存储内存。但它适用于函数中的变量。我想这里讨论的是函数堆栈。虽然可以在寄存器上分配变量,但当调用另一个函数时,该变量必须存储在堆栈上,否则寄存器只是一个临时占位符,下一个函数可以使用它。因此,如果变量存储在寄存器中,它必须位于函数stackframe上,以在函数调用中保留值。@Caesar:因为它本质上是非应答的。你是对的,它与任何其他类型的函数都是一样的,但是你没有解释它的实际含义。@Drewall它回答了这个问题,如果他需要知道一个正则函数如何分配内存,那么这完全是另一个问题。@Caesar:也许吧。但我认为问题的本质是对调用堆栈的机制缺乏理解。
Call to rev(NODE1)
Check if it is NULL
Point to next NODE i.e. NODE2

Call to rev(NODE2)

Check if It is NULL
Point to next NODE i.e. NULL

Call to rev(NULL)

Check if It is NULL
Pointer will be returned With head = NULL