¿Por qué puedo cambiar el valor de una variable const char*?

4 minutos de lectura

¿Por que puedo cambiar el valor de una variable const
cris

¿Por qué funciona el siguiente código en C?

const char* str = NULL;
str = "test";
str = "test2";

Dado que str es un puntero a un carácter constante, ¿por qué se nos permite asignarle diferentes literales de cadena? Además, ¿cómo podemos proteger a str para que no se modifique? Parece que esto podría ser un problema si, por ejemplo, más tarde asignamos str a una cadena más larga que terminó escribiendo sobre otra parte de la memoria.

Debo agregar que en mi prueba, imprimí la dirección de memoria de str antes y después de cada una de mis tareas y nunca cambió. Entonces, aunque str es un puntero a un const char, la memoria en realidad se está modificando. Me preguntaba si tal vez este es un problema heredado con C.

  • Relacionado: stackoverflow.com/questions/162480/const-in-c

    – Ates Goral

    13 de enero de 2009 a las 19:30

  • Supongo que en realidad estaba imprimiendo la dirección de la variable str, que no cambia, su valor cambia.

    – Greg Rogers

    13 de enero de 2009 a las 19:38

Está cambiando el puntero, que no es const (lo que apunta es const).

Si desea que el puntero sea constante, la declaración se vería así:

char * const str = "something";

o

char const * const str = "something";  // a const pointer to const char
const char * const str = "something";  //    same thing

Los punteros constantes a datos que no son constantes suelen ser una construcción menos útil que el puntero a constante.

  • Sin embargo, hice una prueba. Asigné str a una cadena e imprimí la cadena y su dirección de memoria. Luego, asigné str a otra cadena y nuevamente imprimí la cadena y su dirección de memoria. El literal de cadena había cambiado pero la dirección no.

    – Chris

    13 de enero de 2009 a las 19:18

  • ¿Imprimió la dirección del puntero o la dirección a la que apunta el puntero?

    – mipadi

    13 de enero de 2009 a las 19:30

  • Gracias a todos. ¡Sí, estaba imprimiendo la dirección del puntero, no los datos! Lo que me desconcertó en este problema es cómo C trata con los literales de cadena. Puede asignar un literal de cadena a un char* pero no puede asignar un número entero a un int* de la misma manera, por ejemplo.

    – Chris

    13 de enero de 2009 a las 20:15

  • @Chris: eso es porque un literal de cadena es en realidad un carácter[]que se puede convertir implícitamente en un puntero a su primer elemento

    – Cristóbal

    13 de enero de 2009 a las 21:24

  • Vale, eso tiene sentido. ¡Gracias!

    – Chris

    13 de enero de 2009 a las 22:31

1647545527 802 ¿Por que puedo cambiar el valor de una variable const
matthew crumley

Además, ¿cómo podemos proteger a str para que no se modifique?

char * const str1; // str1 cannot be modified, but the character pointed to can
const char * str2; // str2 can be modified, but the character pointed to cannot
const char * const str3 // neither str3 nor the character pointed to can be modified.

La forma más fácil de leer esto es comenzar desde el nombre de la variable y leer hacia la izquierda:

  • str1 es un constantehormiga puntero a un carbonizarseactor
  • str2 es un puntero a un carbonizarseactor constantehormiga
  • str3 es un constantehormiga puntero a un carbonizarseactor constantehormiga

NOTA: la lectura de derecha a izquierda no funciona en el caso general, pero para declaraciones simples es una forma sencilla de hacerlo. Encontre un applet java basado en código de “El lenguaje de programación C” que puede descifrar declaraciones con una explicación completa de cómo hacerlo.

  • Alguien podría descartar la const si estuviera realmente determinada, pero si el compilador coloca los caracteres en una página de solo lectura, modificarlos causará una falla en el tiempo de ejecución.

    – Marklam

    5 de agosto de 2009 a las 10:18

  • Técnicamente, el compilador y el enlazador juntos. Los interruptores dependen de las herramientas que esté utilizando.

    – Marklam

    5 de agosto de 2009 a las 10:20

En una nota relacionada, definitivamente eche un vistazo a “puntero const versus puntero a const“. Ayuda con lo que algunas personas llaman corrección constante. Lo guardo en mis marcadores para poder consultarlo de vez en cuando.

Lo que estás buscando puede ser la sintaxis…

const char* const str = NULL;
str = "test";
str = "test2";

Observe la “const” después de char* que produce un error de compilación al intentar compilar/construir.

1647545528 432 ¿Por que puedo cambiar el valor de una variable const
Joel Coehoorn

La memoria para los literales de cadena se asigna en la pila, y todas sus asignaciones cambian el str puntero para apuntar a esas direcciones de memoria. El carácter constante al que apuntaba inicialmente no ha cambiado en absoluto.

  • literales de cadena asignados en la pila? er… Se asignan en la sección de datos.

    – Serge Wautier

    13 de enero de 2009 a las 19:37

Además, declarar una variable como const significa que la variable es de solo lectura; ¡no significa que el valor sea constante!

  • literales de cadena asignados en la pila? er… Se asignan en la sección de datos.

    – Serge Wautier

    13 de enero de 2009 a las 19:37

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad