Dadas las declaraciones
char *s0 = "hello world";
char s1[] = "hello world";
suponga el siguiente mapa de memoria hipotético:
0x01 0x02 0x03 0x04
0x00008000: 'h' 'e' 'l' 'l'
0x00008004: 'o' ' ' 'w' 'o'
0x00008008: 'r' 'l' 'd' 0x00
...
s0: 0x00010000: 0x00 0x00 0x80 0x00
s1: 0x00010004: 'h' 'e' 'l' 'l'
0x00010008: 'o' ' ' 'w' 'o'
0x0001000C: 'r' 'l' 'd' 0x00
La cadena literal "hello world"
es una matriz de 12 elementos de char
( const char
en C++) con una duración de almacenamiento estática, lo que significa que la memoria para ella se asigna cuando el programa se inicia y permanece asignada hasta que el programa termina. Intentar modificar el contenido de un literal de cadena invoca un comportamiento indefinido.
La línea
char *s0 = "hello world";
define s0
como un puntero a char
con una duración de almacenamiento automática (lo que significa que la variable s0
sólo existe para el ámbito en el que se declara) y copia el dirección de la cadena literal ( 0x00008000
en este ejemplo). Tenga en cuenta que, dado que s0
apunta a un literal de cadena, no debe utilizarse como argumento de ninguna función que intente modificarlo (p. ej, strtok()
, strcat()
, strcpy()
etc.).
La línea
char s1[] = "hello world";
define s1
como una matriz de 12 elementos de char
(la longitud se toma del literal de la cadena) con una duración de almacenamiento automática y copia el contenidos del literal al Array. Como puedes ver en el mapa de memoria, tenemos dos copias de la cadena "hello world"
la diferencia es que se puede modificar la cadena contenida en s1
.
s0
y s1
son intercambiables en la mayoría de los contextos; he aquí las excepciones:
sizeof s0 == sizeof (char*)
sizeof s1 == 12
type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char
Puede reasignar la variable s0
para apuntar a una cadena literal diferente o a otra variable. No se puede reasignar la variable s1
para apuntar a un Array diferente.