Saltar al contenido

conversión obsoleta de string constante a ‘char *’

Posterior a de esta extensa recopilación de datos solucionamos este conflicto que pueden tener muchos de nuestros usuarios. Te brindamos la respuesta y nuestro objetivo es que sea de mucha ayuda.

Solución:

Como es mi costumbre, voy a proporcionar un poco de información técnica de antecedentes sobre los por qué y los motivos de este error.

Examinaré cuatro formas diferentes de inicializar cadenas C y veré cuáles son las diferencias entre ellas. Estas son las cuatro formas en cuestión:

char *text = "This is some text";
char text[] = "This is some text";
const char *text = "This is some text";
const char text[] = "This is some text";

Ahora, para esto, voy a querer cambiar la tercera letra “i” en una “o” para que sea “Eso es un texto”. Eso podría, en todos los casos (usted pensaría), lograrse mediante:

text[2] = 'o';

Ahora veamos lo que cada forma de declarar el string hace y como eso text[2] = 'o'; declaración afectaría las cosas.

Primero, la forma más común: char *text = "This is some text";. ¿Qué significa esto literalmente? Bueno, en C, significa literalmente “Cree una variable llamada text que es un puntero de lectura y escritura a este string literal que se mantiene en un espacio de solo lectura (código). “. Si tiene la opción -Wwrite-strings encendido, aparece una advertencia como se ve en la pregunta anterior.

Básicamente, eso significa “Advertencia: ha intentado hacer que una variable de lectura-escritura apunte a un área en la que no puede escribir”. Si lo intenta y luego establece el tercer carácter en “o”, de hecho estaría tratando de escribir en un área de solo lectura y las cosas no saldrán bien. En una PC tradicional con Linux que da como resultado:

Fallo de segmentación

Ahora el segundo: char text[] = "This is some text";. Literalmente, en C, eso significa “Crear un array de tipo “char” e inicializarlo con los datos “This is some text 0”. El tamaño de la array será lo suficientemente grande para almacenar los datos “. De modo que en realidad asigna RAM y copia el valor” Este es un texto 0 “en el tiempo de ejecución. Sin advertencias, sin errores, perfectamente válido. Y la forma correcta de hacerlo si quieres poder editar los datos. Intentemos ejecutar el comando text[2] = 'o':

Eso es un texto

Funcionó perfectamente. Bien.

Ahora la tercera forma: const char *text = "This is some text";. De nuevo, el significado literal: “Cree una variable llamada” texto “que sea un solo lectura puntero a estos datos en la memoria de solo lectura “. Tenga en cuenta que tanto el puntero como los datos ahora son de solo lectura. Sin errores, sin advertencias. ¿Qué sucede si intentamos ejecutar nuestro comando de prueba? Bueno, no podemos. El compilador ahora es inteligente y sabe que estamos tratando de hacer algo malo:

error: asignación de ubicación de solo lectura ‘* (texto + 2u)’

Ni siquiera se compilará. Intentar escribir en la memoria de solo lectura ahora está protegido porque le hemos dicho al compilador que nuestro puntero es a la memoria de solo lectura. Por supuesto que no tener para apuntar a la memoria de solo lectura, pero si lo apunta a la memoria de lectura y escritura (RAM), esa memoria seguirá protegida para que el compilador no escriba en ella.

Finalmente la última forma: const char text[] = "This is some text";. De nuevo, como antes con [] asigna un array en RAM y copia los datos en él. Sin embargo, ahora esta es una versión de solo lectura. array. No puede escribir en él porque el puntero está etiquetado como const. Intentar escribir en él da como resultado:

error: asignación de ubicación de solo lectura ‘* (texto + 2u)’

Entonces, un resumen rápido de dónde estamos:

Este formulario es completamente inválido y debe evitarse a toda costa. Abre la puerta a todo tipo de cosas malas que suceden:

char *text = "This is some text";

Este formulario es el correcto si desea que los datos sean editables:

char text[] = "This is some text";

Este formulario es el correcto si desea cadenas que no se editarán:

const char *text = "This is some text";

Esta forma parece un desperdicio de RAM, pero tiene sus usos. Será mejor que lo olvides por ahora.

const char text[] = "This is some text";

Para desarrollar la excelente respuesta de Makenko, hay una buena razón por la que el compilador le advierte sobre esto. Hagamos un boceto de prueba:

char *foo = "This is some text";
char *bar = "This is some text";

void setup ()
  
  Serial.begin (115200);
  Serial.println ();
  foo [2] = 'o';     // change foo only
  Serial.println (foo);
  Serial.println (bar);
    // end of setup

void loop ()
  
    // end of loop

Tenemos dos variables aquí, foo y bar. Yo modifico una de los de setup (), pero mira cuál es el resultado:

Thos is some text
Thos is some text

Ellos ambos se cambió!

De hecho si miramos las advertencias vemos:

sketch_jul14b.ino:1: warning: deprecated conversion from string constant to ‘char*’
sketch_jul14b.ino:2: warning: deprecated conversion from string constant to ‘char*’

El compilador sabe que esto es dudoso, ¡y es correcto! La razón de esto es que el compilador (razonablemente) espera que string las constantes no cambian (ya que son constantes). Por lo tanto, si se refiere a la string constante "This is some text" varias veces en su código se le permite asignar el mismo memoria a todos ellos. Ahora, si modifica uno, ¡modifica todos!

O deja de intentar pasar un string constante donde una función toma un char*, o cambie la función para que tome un const char* en lugar de.

Cadena como “aleatorio string”son constantes.

Comentarios y puntuaciones del post

Acuérdate de que te concedemos valorar esta sección .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *