Alcance vs. Tiempo de vida de la variable

¿Cuál es la relación entre el scope y la vida útil de una variable? Si una variable está fuera del scope, se permite sobrescribir la memoria de otra variable, o se reserva el espacio hasta que se deja la función.

Estoy preguntando porque quiero saber si el código siguiente funciona realmente, o si puede ser que * p pueda estar indefinido

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

¿Qué es el scope?

El scope es la región o sección de código donde se puede acceder a una variable.

¿Qué es una vida?

Lifetime es la duración de tiempo donde un objeto / variable está en un estado válido.

Para, variables no estáticas automáticas / locales Lifetime está limitado a su Scope .
En otras palabras, las variables automáticas se destruyen automágicamente una vez que finaliza el scope ( { , } ) en el que se crearon. De ahí el nombre automático para comenzar.

¿Qué está mal en tu ejemplo de código?

Entonces, sí, su código tiene un comportamiento indefinido .

En su scope de ejemplo de *p encuentra todo el cuerpo de la función después de haber sido creado.
Sin embargo, x es una variable local / automática no estática y, por lo tanto, la duración de x termina con su scope, es decir, el corchete de cierre } en el que se creó, una vez que el scope finaliza x no existe. *p apunta a algo que ya no existe.

Tenga en cuenta que técnicamente x no existe más allá de su scope, sin embargo, puede suceder que el comstackdor no elimine el contenido de x y uno pueda acceder a los contenidos de x más allá de su scope a través de un puntero ( como lo hace ). Sin embargo, un código que hace esto no es un código válido de C ++. Es un código que invoca un comportamiento indefinido. Lo que significa que cualquier cosa puede suceder ( incluso puede ver el valor de x intacto ) y uno no debe esperar comportamientos observables de dicho código.

C11 Sección 6.2.1 Párrafo 2

Para cada entidad diferente que designa un identificador, el identificador es visible (es decir, se puede usar) solo dentro de una región del texto del progtwig llamada su scope. Las diferentes entidades designadas por el mismo identificador tienen diferentes ámbitos o están en diferentes espacios de nombres

.

C11 Sección 6.2.4 Párrafo 2

La duración de un objeto es la porción de ejecución del progtwig durante la cual se garantiza que el almacenamiento está reservado para él.

En su caso, x es local al bloque y su duración, por lo tanto, no se puede acceder a x por su nombre fuera del bloque, ya que su duración está limitada a su bloque, la dirección de x ya no se reservará después de abandonar el bloque , por lo tanto, dará como resultado un comportamiento indefinido.

Por otro lado, por ejemplo, digamos una variable local static , en este caso el scope es local al bloque y, por lo tanto, no podemos acceder por su nombre fuera del bloque, pero el tiempo de vida es el progtwig completo, por lo que podemos usar la dirección de la variable en cualquier parte del progtwig mientras se está ejecutando. Este ejemplo debería ayudar a obtener la diferencia.

Los objetos (es decir, las cosas subyacentes reales que almacenan valores) tienen tiempos de vida.

Las variables (es decir, las cosas utilizadas para referirse a los objetos) tienen scope.

De cualquier manera, y = *p invoca un comportamiento indefinido; el objeto referido por x es automático , su vida útil termina cuando x sale del scope.

¿Cuál es la relación entre el scope y la vida útil de una variable?

Como dijo Oli, las variables tienen scope y objetos de por vida. El scope de una variable y la duración de la misma están vinculados, pero puede tener objetos cuya duración se extiende más allá del ámbito en el que se crearon:

 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 } 

En su caso particular, la variable x termina su vida útil cuando el ámbito en el que se creó está cerrado, por lo que tiene un comportamiento indefinido.

Si una variable está fuera del scope, se permite sobrescribir la memoria de otra variable, o se reserva el espacio hasta que se deja la función.

Este es un detalle de la implementación. El acceso a la variable es un comportamiento indefinido en todos los casos y dado que no todos los casos deben ser iguales , y si la variable tenía un destructor no trivial, se llamaría al final del scope, por lo que no importa si la memoria está allí o no. el objeto ya no está allí. Dicho esto, en muchos casos los comstackdores no liberarán la memoria en la función (es decir, no volverán a colocar el puntero del marco) cuando una variable se sale del scope, pero podrían reutilizar el mismo espacio para contener otras variables en la misma función.

He ejecutado su progtwig y la salida es 5. La salida sigue siendo 5 aunque la variable x se destruye después de que el segundo ‘}’ se debe a que la ubicación de la memoria no se sobrescribe con ninguna otra variable.Si usted tiene una gran cantidad de código después al final del segundo ámbito, es muy probable que se sobrescriba la ubicación de memoria que previamente pertenecía a ‘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. 

El estándar define que se permite sobrescribir la memoria una vez que se deja el scope. La implementación del comstackdor lo hace reservado y libre. Las optimizaciones en tiempo de comstackción pueden mover la asignación de la stack para que no reflejen su orden.

Su código no invoca el comportamiento indefinido y no debe ser utilizado. Su código podría funcionar, ya que el valor de escritura de y ocurre DESPUÉS de tomar el valor p de puntos.