Lifetime
Каждый объект в C существует, имеет постоянный адрес, сохраняет последнее записанное значение (кроме случаев, когда значение неопределено) , и, для VLA, сохраняет свой размер (начиная с C99) в течение части выполнения программы, известной как время жизни этого объекта.
Для объектов, объявленных с автоматической, статической и потоковой длительностью хранения, время жизни равно их storage duration (обратите внимание на разницу между не-VLA и VLA automatic storage duration).
Для объектов с выделенной продолжительностью хранения время жизни начинается, когда функция выделения возвращает результат (включая возврат из realloc ) и заканчивается, когда вызывается realloc или функция освобождения памяти. Заметьте, что поскольку выделенные объекты не имеют объявленного типа , тип lvalue-выражения, впервые использованного для доступа к этому объекту, становится его эффективным типом .
Доступ к объекту за пределами его времени жизни является неопределённым поведением.
int* foo(void) { int a = 17; // переменная a имеет автоматическую продолжительность хранения return &a; } // время жизни a завершается int main(void) { int* p = foo(); // p указывает на объект после завершения времени жизни ("висячий указатель") int n = *p; // неопределённое поведение }
Указатель на объект (или за его пределами), время жизни которого завершилось, имеет неопределённое значение.
Время жизни временных объектов
Объекты структур и объединений с элементами-массивами (прямыми или членами вложенных структур/объединений), которые обозначаются не-lvalue выражениями , имеют временное время жизни . Временное время жизни начинается при вычислении выражения, ссылающегося на такой объект, и заканчивается в следующей точке следования (до C11) при завершении содержащего полного выражения или полного декларатора (начиная с C11) .
Любая попытка модификации объекта с временным временем жизни приводит к неопределённому поведению.
struct T { double a[4]; }; struct T f(void) { return (struct T){3.15}; } double g1(double* x) { return *x; } void g2(double* x) { *x = 1.0; } int main(void) { double d = g1(f().a); // C99: НО обращение к a[0] в g1, время жизни которого завершилось // в точке следования в начале g1 // C11: OK, d равно 3.15 g2(f().a); // C99: НО модификация a[0], время жизни которого завершилось в точке следования // C11: НО попытка модификации временного объекта }
Ссылки
- Стандарт C17 (ISO/IEC 9899:2018):
-
- 6.2.4 Время жизни объектов (стр: 30)
- Стандарт C11 (ISO/IEC 9899:2011):
-
- 6.2.4 Время жизни объектов (стр. 38-39)
- Стандарт C99 (ISO/IEC 9899:1999):
-
- 6.2.4 Время жизни объектов (стр. 32)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
-
- 3.1.2.4 Время хранения объектов
Смотрите также
|
Документация C++
для
Время жизни объекта
|