Sí, la vida útil de una variable local está dentro del alcance ( {
, }
) en el que se crea.
Las variables locales tienen almacenamiento automático o local. Automático porque se destruyen automáticamente una vez que finaliza el alcance dentro del cual se crearon.
Sin embargo, lo que tiene aquí es un literal de cadena, que se asigna en una memoria de solo lectura definida por la implementación. Los literales de cadena son diferentes de las variables locales y permanecen vivos durante toda la vida útil del programa. Tienen una duración estática [Ref 1] de por vida.
¡Una palabra de precaución!
Sin embargo, tenga en cuenta que cualquier intento de modificar el contenido de un literal de cadena es un comportamiento indefinido (UB). Los programas de usuario no pueden modificar el contenido de una cadena literal.
Por lo tanto, siempre se recomienda usar un const
while declarando una cadena literal.
const char*p = "string";
en vez de,
char*p = "string";
De hecho, en C ++ está en desuso declarar un literal de cadena sin el const
aunque no en C. Sin embargo, declarar un literal de cadena con un const
le da la ventaja de que los compiladores normalmente le darían una advertencia en caso de que intente modificar el literal de cadena en segundo caso.
Programa de muestra :
#include<string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[]="Sample string";
strcpy(str1,source);
strcpy(str2,source);
return 0;
}
Salida:
cc1: las advertencias se tratan como errores
prog.c: En la función 'main':
prog.c: 9: error: pasar el argumento 1 de 'strcpy' descarta los calificadores del tipo de destino del puntero
Observe que el compilador advierte para el segundo caso, pero no para el primero.
Para responder a la pregunta de un par de usuarios aquí:
¿Cuál es el trato con los literales integrales?
En otras palabras, ¿es válido el siguiente código?
int *foo()
{
return &(2);
}
La respuesta es no, este código no es válido. Está mal formado y dará un error de compilación.
Algo como:
prog.c:3: error: lvalue required as unary ‘&’ operand
Los literales de cadena son valores l, es decir: puede tomar la dirección de un literal de cadena, pero no puede cambiar su contenido.
Sin embargo, cualquier otro literales ( int
, float
, char
, etc.) son los valores de r (el estándar C utiliza el término el valor de una expresión para estos) y su dirección no puede ser tomada en absoluto.
[Ref 1] Estándar C99 6.4.5 / 5 "Literales de cadena - Semántica":
En la fase de traducción 7, se agrega un byte o código de valor cero a cada secuencia de caracteres multibyte que resulta de una cadena literal o literales. La secuencia de caracteres multibyte se usa luego para inicializar una matriz de duración de almacenamiento estático y la longitud suficiente para contener la secuencia . Para los literales de cadenas de caracteres, los elementos de la matriz tienen el tipo char y se inicializan con los bytes individuales de la secuencia de caracteres multibyte; para literales de cadena ancha, los elementos de la matriz tienen el tipo wchar_t y se inicializan con la secuencia de caracteres anchos ...
No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores apropiados. Si el programa intenta modificar dicha matriz, el comportamiento no está definido .
int rc
. Su vida finaliza en cada una de lasreturn
-s. Los punteros que está devolviendo son a cadenas literales. Los literales de cadena tienen una duración de almacenamiento estática: su vida útil es al menos tan larga como la del programa.