Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

427
Visualizações
Cuándo asignar memoria a char *

Estoy un poco confundido sobre cuándo asignar memoria a un char * y cuándo señalarlo a una cadena const.

Sí, entiendo que si deseo modificar la cadena, necesito asignarle memoria.

Pero en los casos en que no deseo modificar la cadena a la que apunto y solo necesito pasar el valor, ¿debería hacer lo siguiente? ¿Cuáles son las desventajas de los pasos siguientes en comparación con la asignación de memoria con malloc ?

 char *str = NULL; str = "This is a test"; str = "Now I am pointing here";
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Intentemos nuevamente su ejemplo con el indicador de advertencia del compilador -Wwrite-strings , verá una advertencia:

 warning: initialization discards 'const' qualifier from pointer target type

Esto se debe a que el tipo de "Esto es una prueba" es const char * , no char * . Entonces, está perdiendo la información constante cuando asigna la dirección literal al puntero.

Por razones históricas, los compiladores le permitirán almacenar cadenas literales que son constantes en variables no constantes.

Sin embargo, esto es un mal comportamiento y le sugiero que use -Wwrite-strings todo el tiempo.

Si quieres probarlo por ti mismo, intenta modificar la cadena:

 char *str = "foo"; str[0] = 'a';

El comportamiento de este programa no está definido, pero es posible que vea una falla de segmentación en muchos sistemas. Al ejecutar este ejemplo con Valgrind , verá lo siguiente:

 Process terminating with default action of signal 11 (SIGSEGV) Bad permissions for mapped region at address 0x4005E4

El problema es que el binario generado por su compilador almacenará los literales de cadena en una ubicación de memoria que es de solo lectura . Al intentar escribir en él provocas un fallo de segmentación .

Lo que es importante entender es que aquí se trata de dos sistemas diferentes:

  1. El sistema de escritura C, que es algo que lo ayuda a escribir el código correcto y puede "silenciarse" fácilmente (mediante conversión, etc.)

  2. Los permisos de la página de memoria del kernel que están aquí para proteger su sistema y que siempre se respetarán.

Nuevamente, por razones históricas, este es un punto donde 1. y 2. no están de acuerdo. O para ser más claros, 1. es mucho más permisivo que 2. (lo que resulta en que el núcleo elimine su programa).

¡Así que no se deje engañar por el compilador, los literales de cadena que está declarando son realmente constantes y no puede hacer nada al respecto!

Teniendo en cuenta que su puntero str leer y escribir está bien. Sin embargo, para escribir el código correcto, debe ser un const char * y no un char * . Con el siguiente cambio, su ejemplo es una pieza válida de C:

 const char *str = "some string"; str = "some other string";

( const char * puntero a una cadena const)

En este caso, el compilador no emite ninguna advertencia. Lo que escriba y lo que estará en la memoria una vez que se ejecute el código coincidirá.

Nota: Un puntero const a una cadena const siendo const char *const :

 const char *const str = "foo";

La regla general es: sé siempre lo más constante posible.

Si necesita modificar la cadena, use la asignación dinámica (malloc() o mejor, alguna función de manipulación de cadenas de nivel superior como strdup, etc. de la libc), si no es necesario, use un literal de cadena.

over 4 years ago · Santiago Trujillo Relatório

0

Si sabe que str siempre será de solo lectura, ¿por qué no declararlo como tal?

 char const * str = NULL; /* OR */ const char * str = NULL;

Bueno, en realidad hay una razón por la que esto puede ser difícil: cuando pasa la cadena a una función de solo lectura que no se declara como tal. Suponga que está utilizando una biblioteca externa que declara esta función:

 int countLettersInString(char c, char * str); /* returns the number of times `c` occurs in `str`, or -1 if `str` is NULL. */

Esta función está bien documentada y sabe que no intentará cambiar la cadena str , pero si la llama con una cadena constante, ¡su compilador podría advertirle! Usted sabe que no tiene nada de peligroso, pero su compilador no.

¿Por qué? Porque en lo que respecta al compilador, tal vez esta función intente modificar el contenido de la cadena, lo que haría que su programa fallara. Tal vez confía mucho en esta biblioteca y hay muchas funciones que se comportan de esta manera. Entonces, tal vez sea más fácil no declarar la cadena como const en primer lugar, pero luego depende de usted asegurarse de no intentar modificarla.

Por otro lado, si usted es el que escribe la función countLettersInString , simplemente asegúrese de que el compilador sepa que no modificará la cadena al declararla con const :

 int countLettersInString(char c, char const * str);

De esa manera, aceptará cadenas constantes y no constantes sin problemas.

over 4 years ago · Santiago Trujillo Relatório

0

Una desventaja de usar literales de cadena es que tienen restricciones de longitud. Por lo tanto, debe tener en cuenta el documento ISO/IEC:9899 (énfasis mío)

5.2.4.1 Límites de traducción

1 La implementación deberá poder traducir y ejecutar al menos un programa que contenga al menos una instancia de cada uno de los siguientes límites:

[...]

— 4095 caracteres en un literal de cadena de caracteres o literal de cadena ancha (después de la concatenación)

Entonces, si su texto constante excede este conteo (lo que algunas veces puede ser posible, especialmente si escribe un servidor web dinámico en C), tiene prohibido usar el enfoque de cadena literal si desea permanecer independiente del sistema.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda