Spec-Zone.ru › C

Срок жизни

Каждый объект в 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API