Срок жизни
Каждый объект в C существует, имеет постоянный адрес, сохраняет последнее сохранённое значение (за исключением случаев, когда значение неопределённо), и, для VLA, сохраняет свой размер(с C99) в течение части выполнения программы, известной как срок жизни этого объекта.
Для объектов, объявленных с автоматическим, статическим и потоковым временем жизни, срок жизни равен их времени хранения (обратите внимание на разницу между не-VLA и VLA автоматическим временем хранения).
Для объектов с выделенным временем хранения срок жизни начинается, когда функция выделения возвращает значение (включая возврат из realloc) и заканчивается, когда вызывается функция realloc или функция освобождения. Обратите внимание, что поскольку выделенные объекты не имеют объявленного типа, тип выражения lvalue, впервые используемого для доступа к этому объекту, становится его эффективным типом.
Доступ к объекту за пределами его срока жизни приводит к неопределённому поведению.
int* foo(void) {
int a = 17; // a has automatic storage duration
return &a;
} // lifetime of a ends
int main(void) {
int* p = foo(); // p points to an object past lifetime ("dangling pointer")
int n = *p; // undefined behavior
}Указатель на объект (или за объектом), срок жизни которого закончился, имеет неопределённое значение.
Временный срок жизни
Объекты struct и union с членами массива (либо прямыми, либо членами вложенных struct/union членов), которые обозначаются выражениями, не являющимися 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: UB access to a[0] in g1 whose lifetime ended
// at the sequence point at the start of g1
// C11: OK, d is 3.15
g2(f().a); // C99: UB modification of a[0] whose lifetime ended at the sequence point
// C11: UB attempt to modify a temporary object
}Ссылки
- Стандарт 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++ по Срок жизни объекта |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/lifetime