Почему существует разница при назначении массива с ключевым словом stati c и без указателя? - PullRequest
3 голосов
/ 29 марта 2020

Приведенный ниже код работает правильно и дает вывод 4:

int main()
{

    int *res = valout();
    printf("%d", res[0]);
}

int *valout()
{
    static int arr[] = {4, 5, 6};
    return arr;
}

Приведенный ниже код возвращает ошибку сегментации:

int main()
{

    int *res = valout();
    printf("%d", res[0]);
}

int *valout()
{
    int arr[] = {4, 5, 6};
    return arr;
}

Почему мы получаем ошибку в случае 2 и не в случае 1? Какую роль здесь играет ключевое слово stati c? Пожалуйста, уточните этот вопрос.

Ответы [ 3 ]

5 голосов
/ 29 марта 2020

Это потому, что:

static int arr[] = {4, 5, 6};

создает массив static (очевидно), определяемый как переменная, которая существует с момента ее создания до выхода из программы.

С другой стороны:

int arr[] = {4, 5, 6};

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

В обоих случаях return arr возвращает адрес первого элемента этого массива. К сожалению, с не static вариантом, нет правильного способа использовать этот адрес, потому что базовый объект, на который он ссылается, перестал быть. Следовательно, он будет жаловаться на это.

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

4 голосов
/ 29 марта 2020

Поскольку существует переменная между переменной stati c и локальной переменной, поэтому в первой программе при определении

static int arr[] = {4, 5, 6};

эта переменная (arr) будет существовать (определять) до тех пор, пока fi sh программы, поэтому, когда вы вызываете функцию valout () в главной функции, затем выводите первый элемент, который существует в переменной stati c, он по-прежнему завершается (так как он не будет удален из памяти до завершения программы, но в вторая программа, которую вы определяете массив как (локальная переменная), поэтому он будет определяться между {} функции valout () только для того, чтобы при вызове его в основной функции

 int *res = valout();

программа выполняла эту функцию, но вы хотите напечатать первый элемент компилятора arr, его не видно, так как он будет удален из памяти после выхода из функции valout ()

1 голос
/ 29 марта 2020

static переменные имеют stati c продолжительность хранения, которая имеет продолжительность жизни программы.

automati c переменные имеют automati c длительность хранения - и существует только до тех пор, пока они являются областью действия в вашем случае определяется область действия функции.

Когда вы возвращаете ссылку на автоматическую переменную c - вы возвращаете ссылку на несуществующий объект. Это UB.

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