Namespaces
Variants

Lifetime

From cppreference.net

Todo objeto en C existe, tiene una dirección constante, conserva su último valor almacenado (excepto cuando el valor es indeterminado) , y, para VLA, conserva su tamaño (desde C99) durante una porción de la ejecución del programa conocida como la duración de este objeto.

Para los objetos que se declaran con duración de almacenamiento automático, estático y de hilo, su tiempo de vida es igual a su duración de almacenamiento (nótese la diferencia entre la duración de almacenamiento automático no-VLA y VLA).

Para los objetos con duración de almacenamiento asignado, el tiempo de vida comienza cuando la función de asignación retorna (incluyendo el retorno desde realloc ) y termina cuando se llama a la función realloc o de desasignación. Nótese que dado que los objetos asignados no tienen tipo declarado , el tipo de la expresión lvalue utilizada por primera vez para acceder a este objeto se convierte en su tipo efectivo .

Acceder a un objeto fuera de su tiempo de vida es comportamiento indefinido.

int* foo(void) {
    int a = 17; // a tiene duración de almacenamiento automático
    return &a;
}  // finaliza la vida útil de a
int main(void) {
    int* p = foo(); // p apunta a un objeto tras finalizar su vida útil ("puntero colgante")
    int n = *p; // comportamiento indefinido
}

Un puntero a un objeto (o uno más allá del objeto) cuyo ciclo de vida ha finalizado tiene un valor indeterminado.

Duración temporal

Los objetos de estructura y unión con miembros de arreglo (ya sean directos o miembros de estructuras/uniones anidadas) que son designados por expresiones no lvalue , tienen tiempo de vida temporal . El tiempo de vida temporal comienza cuando se evalúa la expresión que se refiere a dicho objeto y termina en el siguiente punto de secuencia (hasta C11) cuando termina la expresión completa o declarador completo que lo contiene (desde C11) .

Cualquier intento de modificar un objeto con lifetime temporal resulta en comportamiento indefinido.

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: AC acceso a a[0] en g1 cuyo tiempo de vida finalizó
                          //      en el punto de secuencia al inicio de g1
                          // C11: OK, d es 3.15
    g2(f().a); // C99: AC modificación de a[0] cuyo tiempo de vida finalizó en el punto de secuencia
               // C11: AC intento de modificar un objeto temporal
}

Referencias

  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.2.4 Duración de almacenamiento de objetos (p: 30)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.2.4 Duración de almacenamiento de objetos (p: 38-39)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.2.4 Duración de almacenamiento de objetos (p: 32)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 3.1.2.4 Duración de almacenamiento de objetos

Véase también

Documentación de C++ para Duración de objeto