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

时间:2018-05-01 18:43:34

标签: c recursion memory-management global-variables

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

    recursion(&globalA, &globalB);

    printf("globalA: %i\n", globalA);
    printf("globalB: %i\n", 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: %i\n", globalA);
    printf("globalB: %i\n", globalB);
    recursion(globalA, globalB);
    printf("globalA: %i\n", globalA);
    printf("globalB: %i\n", globalB);
    return 0;
}

当代码在第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

和第二个版本:

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

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

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

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

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

P.S。代码是用clang编译的

1 个答案:

答案 0 :(得分:5)

在&#34;全局&#34;例如,您不必为每次递归在堆栈上创建变量globalAglobalB的新副本,但是仍然需要创建新副本每个递归的堆栈上指针变量ab的值。您不会说出您正在使用的操作系统或ABI,但我希望sizeof(int *)大于sizeof(int)