Разъяснение о возвращаемых значениях и времени жизни переменной - PullRequest
1 голос
/ 18 апреля 2019

Мой вопрос касается возврата значения из вызова функции в c. Я прочитал много вопросов и ответов на эту тему, таких как: Возвращение путаницы с локальной переменной в C

Я также понимаю, что возвращение указателя на локальную переменную является проблемой, поскольку локальная переменная имеет нет ограниченное время жизни после возврата. В моем случае ниже я возвращаю указатель значение , а не указатель на локальную переменную. Это должно быть хорошо, да? (то есть возврат & x был бы плох)

int *foo(int a) {
    int *x;  //local scope local lifetime
    ...
    x = &something_non-local;
    ...
    return x;  //return value of pointer
}
int main(void) {
    int *bar;
    bar = foo(10);
}

1 Ответ

1 голос
/ 18 апреля 2019

Вы можете посмотреть на это так. Переменная представляет место в памяти. Время жизни переменной определяется действительностью этого места в памяти. Место в памяти сохраняет значение. Любая операция копирования просто копирует значения из одного места в памяти в другое.

У каждого такого места памяти есть адрес. Указатель на переменную - это просто еще одна переменная, значение которой является адресом другой переменной. Копия указателя - это просто копия адреса из одного места в другое.

Если переменная объявлена ​​в глобальной области видимости, то ее память будет действительна до выхода из программы. Если переменная объявлена ​​нестатически в процедуре, то ее память действительна до конца этой процедуры. Технически он, вероятно, размещен в стеке, который становится нераспределенным при возврате процедуры, что делает эту память недействительной.

В вашем случае , если указатель x указывает на переменную из глобальной области видимости, сама переменная действительна до выхода из процедуры. Однако оператор return копирует значение из x в другое место непосредственно перед тем, как последнее станет недействительным. В результате значение x окажется в bar. Это значение является адресом статической переменной, которая все еще действительна.

Если вы попытаетесь вернуть адрес x, то есть &x, будет другая история. Это был бы адрес памяти, который существовал внутри процедуры. После возврата он будет указывать на недопустимую ячейку памяти.

Итак, если ваш something_non-local указывает на такую ​​вещь, то вы попали в беду. Он должен указывать на что-то статичное или что-то в куче.

Кстати, malloc выделяет память в куче, которая действует, пока вы не используете free.

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