C - 为什么递归中的全局变量比局部变量使用更多的内存?



我有 2 个版本的 C 代码。

版本1:

#include <unistd.h>
#include <stdio.h>
int globalA = 10000;
int globalB = 0;
int recursion(int *a, int *b)
{
*a = *a - 1;
*b += *a;
if (*a < 1) {
sleep(30);
return *b;
} else {
return recursion(a, b);
}
}
int main()
{
printf("globalA: %in", globalA);
printf("globalB: %in", globalB);
recursion(&globalA, &globalB);
printf("globalA: %in", globalA);
printf("globalB: %in", globalB);
return 0;
}

和版本 2 – 相同的代码但没有指针:

#include <unistd.h>
#include <stdio.h>
int globalA = 10000;
int globalB = 0;
int recursion(int a, int b)
{
a = a - 1;
b += a;
if (a < 1) {
sleep(30);
return b;
} else {
return recursion(a, b);
}
}
int main()
{
printf("globalA: %in", globalA);
printf("globalB: %in", globalB);
recursion(globalA, globalB);
printf("globalA: %in", globalA);
printf("globalB: %in", globalB);
return 0;
}

当代码在第 12 行时,我在 os x 上调用控制台命令 vmmap –sleep(30(;

我的问题是为什么vmmap在第一个版本中显示堆栈的这一行:

VIRTUAL RESIDENT    DIRTY  SWAPPED VOLATILE   NONVOL    EMPTY   REGION
REGION TYPE                        SIZE     SIZE     SIZE     SIZE     SIZE     SIZE     SIZE    COUNT (non-coalesced)
===========                     ======= ========    =====  ======= ========   ======    =====  =======
Stack                             8192K     476K     476K       0K       0K       0K       0K        2

对于第二个版本,这是:

Stack                             8192K     316K     316K       0K       0K       0K       0K        2

因此,版本 1 的堆栈常驻大小比版本 2 的堆栈大小更刨丝。

我认为在版本 2 中,每次递归调用都会在每个新的堆栈帧中创建变量ab的新副本。因此,每次调用递归时,它将消耗堆栈中的更多内存。

而在版本 1 中,不需要制作变量ab的新副本,因为它们是通过引用传递的,并且引用给出的变量是全局的,因此globalA必须在.data memory段中,globalB必须在.bss 段中。因此,堆栈中需要的空间更少。

我错了吗?请向我解释一下这里的诀窍在哪里。

附言代码是用叮当编译的

在"globals"情况下,您不必为每个递归创建globalAglobalB堆栈上的变量的新副本,但您仍然必须为每个递归创建指针变量的新副本a和堆栈b您没有说您正在使用什么操作系统或 ABI,但我希望它是sizeof(int *)大于sizeof(int)的操作系统或 ABI .

最新更新