Понимание того, как хранятся области видимости - PullRequest
2 голосов
/ 15 февраля 2020

Я запутался, как массивы хранятся в исполняемом файле, когда они находятся внутри функций и т. П.

С кодом, приведенным ниже, я считаю, что пространство для значения трех целочисленных значений сохраняется в исполняемый файл.

#include <stdlib.h>

int main() {
    int arr[] = {rand(), rand(), rand()};
}

Я думал о массиве в функции, каждый вызов будет использовать то же пространство, что и другие вызовы, для хранения своего массива. Но потом я подумал, что рекурсивные вызовы перезапишут массивы друг друга. Я не понимаю, как пространство для них остается в стороне, особенно с рекурсией и неизвестным количеством звонков. Я попытался сделать пример:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool myfunc(unsigned val) {
    int arr[] = {rand() % 10, rand() % 10};

    if (val == 0)
        return true;

    myfunc(val - 1);

    printf("%d %d\n", arr[0], arr[1]);
    return false;
}

int main() {
    myfunc(rand() % 50);
}

Я получаю, что элементы массивов хранятся один за другим. Но как для них есть место (в стеке?), Когда неизвестно, сколько их будет?

1 Ответ

0 голосов
/ 16 февраля 2020

Объекты, определенные с локальной областью действия в теле функции с автоматическим хранением c (без ключевого слова static), сохраняются во временном хранилище и автоматически возвращаются при выходе из соответствующей области.

Типичные современные архитектуры используются стек времени выполнения для этого: регистр указателя стека уменьшается при входе в область видимости на фиксированную величину, если размер известен во время компиляции, как в случае с вашими примерами: int arr[] = {rand() % 10, rand() % 10}; определяет массив из 2 int, обычно 8 байт.

Если размер известен только во время выполнения, указатель стека уменьшается на значение, вычисленное во время выполнения, что может привести к неопределенному поведению, если этот размер слишком велик. Указатель стека восстанавливается до исходного значения после выхода из функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...