Почему переменная c ++ не удаляется сразу? [Дубликат]

0

Я хотел бы знать, почему данные, которые указываются при возврате из функции, не удаляются немедленно. В фрагменте кода ниже я ожидаю, что когда я верну адрес x в указатель, чтобы инициализировать его при возврате из функции, данные, хранящиеся в адресе x, должны быть немедленно удалены. Однако я все еще могу получить правильное значение в основном, а затем только после того, как еще одна строка кода вдруг превратится в мусор? Почему это не происходит сразу

int* function(int x)
{
    cout << x << endl; // This outputs 5 as expected
    return &x;
}

int main()
{
    int* a = function(5);


    cout << *a; // This still outputs 5. Why?
    cout << endl;

    cout << *a; // It is garbage here as expected
    cout << endl;

    return 0;
}

благодаря

  • 1
    Переменные не удаляются. Их значения могут быть удалены.
  • 0
    @Niall Даже если бы это было так: это не применимо к локальным переменным (по крайней мере, в C ++), и, конечно, сборка мусора не будет перерабатывать память, пока она не понадобится.
Показать ещё 3 комментария
Теги:
pointers
garbage

4 ответа

2
Лучший ответ

Возврат адреса локальной переменной вызывает неопределенное поведение. Итак, вам просто повезло.

Локальная переменная (выделенная в стеке) удаляется, когда она покидает область видимости, которая в вашем случае есть, когда function() заканчивается. Однако после того, как переменная покидает область действия, память, которую он занимает, не переписывается немедленно, и если эта память не используется повторно, значение x останется там.

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

  • 0
    Или не повезло, в зависимости от обстоятельств :)
  • 0
    Это не ответ на вопрос, который касается времени сбора мусора.
Показать ещё 4 комментария
1

Возвращаемый адрес локальной переменной не определен. Undefined означает, что вы не можете предсказать, выводит ли он правильный ИЛИ неверный результат. К сожалению, вы получили правильный результат.

0

Когда вы возвращаете адрес локальной переменной, результирующий указатель "болтается"; доступ через висячий указатель или даже просто чтение его - это неопределенное поведение. Это означает, что в теории все может случиться. На практике скомпилированный код не возвращает память локальных переменных в функции в ОС; в большинстве ОС он даже не мог этого захотеть. Таким образом, память просто сидит там, пока кто-то другой не использует ее. В случае памяти в функции она будет использоваться повторно при вызове другой функции; до тех пор вы, вероятно, сможете получить к нему доступ и найти старые значения. Отладочные сборки могут преднамеренно зачеркивать память при выходе из функции, но компиляторы основного потока этого не делают. И, конечно, программы, такие как valgrind, могут проверить, что указатель действителен, и регистрировать ошибку (но я не знаю, действительно ли valgrind это поймает).

0

Поскольку вы не должны получать доступ к такой "мусору" (техническому термину), система может иметь дело с ней по своему усмотрению. Например, могут быть другие задачи, завершение которых повлияло бы на правильно написанные программы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню