为什么递归中的全局变量使用的内存多于局部变量?

cof*_*zak 1 c recursion memory-management global-variables

我在C中有2个版本的代码.

版本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: %i\n", globalA);
    printf("globalB: %i\n", globalB);

    recursion(&globalA, &globalB);

    printf("globalA: %i\n", globalA);
    printf("globalB: %i\n", globalB);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和版本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: %i\n", globalA);
    printf("globalB: %i\n", globalB);
    recursion(globalA, globalB);
    printf("globalA: %i\n", globalA);
    printf("globalB: %i\n", globalB);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当代码在第12行时,我在os x上调用console command 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
Run Code Online (Sandbox Code Playgroud)

对于第二个版本:

Stack                             8192K     316K     316K       0K       0K       0K       0K        2
Run Code Online (Sandbox Code Playgroud)

因此版本1的堆栈的常驻大小比版本2大.

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

在版本1中,不需要创建变量ab的新副本, 因为它们是通过引用传递的,并且引用给出的变量是全局的,因此globalA必须位于.data内存段中,而globalB必须位于.bss中细分.结果,堆栈需要的空间更少.

我错了吗?请向我解释这里的诀窍.

PS Code是用clang编译的

zwo*_*wol 5

在"全局"的情况下,你不必创建变量的新副本globalAglobalB堆栈每个递归,但你还是要创建指针变量的新副本ab堆栈每个递归上.你没有说你正在使用什么操作系统或ABI,但我希望它是一个sizeof(int *)大于sizeof(int).