Literales de cadena: puntero versus matriz de caracteres
En esta declaración:
char *a = "string1"
¿Qué es exactamente una cadena literal? Lo es string1
? Porque este hilo ¿Cuál es el tipo de cadenas literales en C y C++? dice algo diferente.
Hasta donde yo sé
int main()
{
char *a = "string1"; //is a string- literals allocated memory in read-only section.
char b[] = "string2"; //is a array char where memory will be allocated in stack.
a[0] = 'X'; //Not allowed. It is an undefined Behaviour. For me, it Seg Faults.
b[0] = 'Y'; //Valid.
return 0;
}
Agregue algunos detalles además de los puntos mencionados anteriormente. Gracias.
Salida de depuración que muestra error en a[0] = 'Y';
Reading symbols from /home/jay/Desktop/MI/chararr/a.out...done.
(gdb) b main
Breakpoint 1 at 0x40056c: file ddd.c, line 4.
(gdb) r
Starting program: /home/jay/Desktop/MI/chararr/a.out
Breakpoint 1, main () at ddd.c:4
4 {
(gdb) n
6 char *a = "string1";
(gdb) n
7 char b[] = "string2";
(gdb)
9 a[0] = 'Y';
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400595 in main () at ddd.c:9
Puede considerar el literal de cadena como "una secuencia de caracteres entre comillas dobles" . Esta cadena debe tratarse como de solo lectura y al intentar modificar esta memoria se produce un comportamiento indefinido . No necesariamente se almacena en la memoria de solo lectura y el tipo es char[]
and not const char[]
, pero aún es un comportamiento indefinido. La razón por la que el tipo no lo es const
es la compatibilidad con versiones anteriores. C no tenía el const
calificativo al principio. En C++, los literales de cadena tienen el tipo const char[]
.
Entonces, ¿por qué se produce un error de segmentación?
- El punto principal es que
char *ptr = "string literal"
apuntaptr
a la memoria de solo lectura donde se almacena el literal de cadena. Entonces, cuando intentas acceder a esta memoria:ptr[0] = 'X'
(que por cierto es equivalente a*(ptr + 0) = 'X'
), es una violación de acceso a la memoria .
Por otro lado: char b[] = "string2";
asigna memoria y copia la cadena "string2"
en ella, por lo que modificarla es válida. Esta memoria se libera cuando b
sale del alcance.
Eche un vistazo al inicializador de cadena literal para una matriz de caracteres.