Подтвердить что ты не робот

Область действия и время жизни переменной

Какова связь между областью действия и временем жизни переменной? Если переменная выходит за пределы области видимости, то ее память может быть перезаписана другой переменной или зарезервировано пространство до тех пор, пока функция не останется.

Я прошу, потому что хочу знать, действительно ли работает код ниже или может быть, что * p может быть undefined

foo() {
  int *p;
  {
    int x = 5; 
    p = &x;
  }
  int y = *p;


}
4b9b3361

Ответ 1

Что такое область видимости?

Область - это область или раздел кода, к которым доступна доступная переменная.

Что такое продолжительность жизни?

Lifetime - это продолжительность времени, когда объект/переменная находится в допустимом состоянии.

Для Автоматические/Локальные нестатические переменные Lifetime ограничены их Scope.
Другими словами, автоматические переменные автоматически уничтожаются после завершения области ({, }), в которой они созданы. Следовательно, имя начинается автоматически.

Что не так в вашем примере кода?

Итак, у вашего кода есть Undefined Поведение.

В вашем примере область *p - это целая часть тела после ее создания.
Тем не менее, x - нестатическая локальная/автоматическая переменная, и, следовательно, время жизни x заканчивается областью видимости, т.е. закрывающей скобкой }, в которой она была создана, после окончания области x не существует, *p указывает на то, что больше не существует.

Обратите внимание, что технически x не существует за пределами его области действия, однако может случиться так, что компилятор не удалил содержимое x, и можно было бы получить доступ к содержимому x за пределами его области действия с помощью указателя ( как и вы). Однако код, который делает это, не является допустимым кодом С++. Это код, вызывающий Undefined Поведение. Это означает, что все может произойти (вы даже можете увидеть, что значение x является неповрежденным), и не следует ожидать наблюдаемого поведения от такого кода.

Ответ 2

Объекты (т.е. фактические базовые вещи, хранящие значения) имеют срок службы.

Переменные (т.е. вещи, используемые для обращения к объектам) имеют область видимости.

В любом случае y = *p вызывает поведение undefined; объект, на который ссылается x, автоматически, его время жизни заканчивается, когда x выходит за пределы области видимости.

Ответ 3

C11 Раздел 6.2.1 Пункт 2

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

.

C11 Раздел 6.2.4 Пункт 2

Время жизни объекта - это часть выполнения программы во время которое, как предполагается, будет зарезервировано для него.

В вашем случае x является локальным для блока и, следовательно, является его временем жизни, поэтому к x невозможно получить доступ к его имени за пределами блока, также потому, что его время жизни ограничено его блоком, адрес x больше не будет зарезервирован после выхода из блока, что приведет к поведению undefined.

С другой стороны, например, скажем, локальная переменная static, в этом случае область локальна для блока и поэтому мы не можем получить доступ к ее имени за пределами блока, но время жизни - это вся программа, поэтому мы можем использовать адрес переменной в любом месте программы во время ее работы. Этот пример должен помочь получить разницу.

Ответ 4

Какова связь между областью действия и временем жизни переменной?

Как заявил Оли, переменные имеют продолжительность жизни и объекты. Область действия переменной и время ее жизни связаны, но вы можете иметь объекты, чье жизненное время выходит за пределы области, в которой они были созданы:

int* f() {
   int *p                    // Variable p
          = new int(1);      // object (call it x)
   return p;                 // p scope ends, p lifetime ends, x survives
}
int main() {
   int *q                    // Variable q
          = f();             // ... points to x
   delete q;                 // x lifetime ends, q is in scope, q is alive
}

В вашем конкретном случае переменная x заканчивает это время жизни, когда область, в которой она была создана, закрыта, поэтому у вас есть поведение undefined.

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

Это деталь реализации. Доступ к переменной - это поведение undefined во всех случаях, и поскольку не все случаи должны быть равны, и если переменная имеет нетривиальный деструктор, она будет вызываться в конце области, поэтому, есть ли там память или нет, не имеет значения: объект больше не существует. При этом во многих случаях компиляторы не будут освобождать память в функции (т.е. они не будут переустанавливать указатель кадра), когда переменная выходит за пределы области видимости, но они могут использовать одно и то же пространство для хранения других переменных в одной и той же функции.

Ответ 5

Я запустил вашу программу, а выход - 5. Выход все равно 5, хотя переменная x уничтожается после второй '}', потому что память не перезаписывается какой-либо другой переменной. Если у вас много кода после окончания второй области действия. Весьма вероятно, что место памяти, ранее принадлежащее "x", перезаписано.

int x = 5; 
*p = &x;
}  //  x lifetime ends after this.but the number '5' is still there in that memory.
   //but it is possible to assign this memory (which previously belong to x) to a new var.

Ответ 6

Стандарт определяет, что память может быть перезаписана после удаления области. Внедрение компилятора делает его зарезервированным и освобожденным. Оптимизация времени компиляции может переместить выделение стека, чтобы они больше не отражали ваш заказ.

Ваш код вызывает поведение undefined и не должен использоваться. Ваш код может действительно работать, поскольку запись значения y происходит ПОСЛЕ того, как значение p указывает на.