У меня есть 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: %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;
}
Я вызываю консольную команду vmmap для os x, когда код находится в строке 12 - 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 и globalB в сегменте .bss . В результате в стеке требуется меньше места.
Я не прав? Пожалуйста, объясните мне, где здесь уловка.
P.S. Код был скомпилирован с помощью clang