Literales de cadena: puntero versus matriz de caracteres

Resuelto Jeyaram asked hace 12 años • 1 respuestas

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
Jeyaram avatar Oct 09 '12 15:10 Jeyaram
Aceptado

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 constes la compatibilidad con versiones anteriores. C no tenía el constcalificativo 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"apunta ptra 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 bsale del alcance.

Eche un vistazo al inicializador de cadena literal para una matriz de caracteres.

LihO avatar Oct 09 '2012 08:10 LihO