Hola Pablo, cuánto tiempo sin hablar.
¿Que pasa con los otros 4 bytes que reserve para la cadena "Hola", se reemplaza por estos?
cadena al principio apunta a "Hola" en donde sea que esté el "H" pues allí es donde está apuntando, siempre que crees una cadena así como lo estás haciendo siempre se agrega un '\0' al final de la cadena( como ya te han dicho), es como si le dijeras al compilador que allí es donde termina la cadena. Ahora cuando haces que cadena apunte a "Sol" entonces la cadena "Hola" seguirá existiendo en la computadora, el problema es que ya no vamos a saber en dónde( al menos que con otro puntero guardes la dirección a la que apuntaba cadena al principio, cuando apuntaba a "Hola"), como ahora cadena apunta a "Sol" y como "Hola" aún sigue existiendo en la computadora pues cadena tendrá otra dirección de memoria.
Entonces al hacer esas asignaciones terminas perdiendo los punteros( quién sabe en dónde irán a terminar), luego
creo que no se podrán liberar( el que se pierde, en este caso se pierde la dirección en donde se aloja "Hola", es como que un puntero no tiene memoria de las cosas a las que apunta, si lo cambias ya no se acordará de dónde apuntaba anteriormente).
Si es C++ entonces tienes a
new y delete para manejar memoria dinámica, con eso como que te obligan a liberar la memoria cuando ya no lo estas utilizando, sino pues tienes que confiar a que la computadora libere la memoria( tipo java (xD)).
Ve fijándote en la dirección:
char* cadena = "Hola";
printf("Dirección %d ",&(*cadena));
cadena = "Sol";
printf("Dirección %d ",&(*cadena));
la dirección de cadena cambia. Luego también puedes guardar a "Hola" en otro puntero:
char* cadena = "Hola";
char* cadena2 = cadena; //salvamos a cadena antes de cambiar a lo que apunta
cadena = "Sol";
printf("%s",cadena);
printf("%s",cadena2);
Ahora cuando el programa termine se libera cadena y cadena2 tranquilamente.