Literales de cuerda

Tengo pocas dudas sobre los literales de cadenas en c ++.

char *strPtr ="Hello" ; char strArray[] ="Hello"; 

Ahora strPtr y strArray se consideran literales de cadena.

Según mi comprensión, los literales de cadenas se almacenan en la memoria de solo lectura, por lo que no podemos modificar sus valores.

No podemos hacer

 strPtr[2] ='a'; and strArray[2]='a'; 

Ambas declaraciones anteriores deben ser ilegales. el comstackdor debe lanzar errores en ambos casos.

El comstackdor mantiene los literales de cadena en la memoria de solo lectura, por lo que si intentamos modificarlos, el comstackdor arroja errores.

También los datos de const también se consideran de solo lectura.

¿Es que ambos literales de cadena y datos de const se tratan de la misma manera? ¿Puedo eliminar la constante usando const_cast desde string literal puede cambiar su valor?

¿Dónde exactamente se almacenan los literales de cadena? (en la sección de datos del progtwig)

Ahora strPtr y strArray se consideran literales de cadena.

No, no lo son. Los literales de cadena son las cosas que ves en tu código. Por ejemplo, el "Hello" . strPtr es un puntero al literal (que ahora se comstack en el ejecutable). Tenga en cuenta que debe ser const char * ; no se puede eliminar legalmente la const según el estándar C y esperar un comportamiento definido al usarla. strArray es una matriz que contiene una copia del literal (comstackdo en el ejecutable).

Ambas declaraciones anteriores deben ser ilegales. el comstackdor debe lanzar errores en ambos casos.

No, no debería. Las dos declaraciones son completamente legales. Debido a las circunstancias, el primero no está definido. Sin embargo, sería un error si fueran punteros para const char .

Hasta donde yo sé, los literales de cadenas pueden definirse de la misma manera que otros literales y constantes. Sin embargo, hay diferencias:

 // These copy from ROM to RAM at run-time: char myString[] = "hello"; const int myInt = 42; float myFloats[] = { 3.1, 4.1, 5.9 }; // These copy a pointer to some data in ROM at run-time: const char *myString2 = "hello"; const float *myFloats2 = { 3.1, 4.1, 5.9 }; char *myString3 = "hello"; // Legal, but... myString3[0] = 'j'; // Undefined behavior! (Most likely segfaults.) 

Mi uso de ROM y RAM aquí son generales. Si la plataforma es solo RAM (por ejemplo, la mayoría de los progtwigs de Nintendo DS), los datos de const pueden estar en la memoria RAM. Las escrituras aún no están definidas. La ubicación de los datos de const no debería importar para un progtwigdor de C ++ normal.

 char *strPtr ="Hello" ; 

Define strPtr un puntero a char apuntando a un literal de cadena "Hello" – el tipo efectivo de este puntero es const char * . No se permite ninguna modificación a través de strPtr al ponente (invoca UB si intentas hacerlo). Esta es una característica de compatibilidad con versiones anteriores para el código C anterior. Esta convención está en desuso en C ++ 0x. Ver el Anexo C:

Cambio: los literales de cadena hechos const El tipo de un literal de cadena se cambia de “array of char” a “array of const char”. […]

Justificación: Esto evita llamar a una función sobrecargada inapropiada, que podría esperar poder modificar su argumento.

Efecto en la función original: cambio a la semántica de la función bien definida. Dificultad de conversión: transformación sintáctica simple, porque los literales de cadena pueden convertirse a char *; (4.2). Los casos más comunes son manejados por una conversión estándar nueva pero obsoleta:

char* p = "abc"; // valid in C, deprecated in C++

char* q = expr ? "abc" : "de"; // valid in C, invalid in C++

¿Qué tan utilizado es: los progtwigs que tienen una razón legítima para tratar los literales de cadena como punteros a la memoria potencialmente modificable son probablemente raros.

 char strArray[] ="Hello"; 

El tipo declarado de strPtr es – es una matriz de caracteres de tamaño no especificado que contiene la cadena Hello incluyendo el terminador nulo, es decir, 6 caracteres. Sin embargo, la inicialización lo convierte en un tipo completo y su tipo es una matriz de 6 caracteres. La modificación a través de strPtr está bien.

¿Dónde exactamente se almacenan los literales de cadena?

Implementación definida.

Los antiguos comstackdores de C y C ++ se basaban puramente en la encoding de bajo nivel, donde los estándares más altos de protección de datos no estaban disponibles, y ni siquiera se pueden aplicar, por lo general, en C y C ++ puedes escribir lo que quieras.

Incluso puede escribir un código para acceder y modificar sus punteros const, si sabe cómo jugar con las direcciones.

Aunque C ++ impone cierta protección de nivel de comstackción, pero no hay protección en el tiempo de ejecución. Sin duda, puede acceder a su propia stack y utilizar sus valores para manipular cualquier dato que entre en el puntero de const.

Esa es la razón por la que se inventó C # donde se aplican estándares de nivel más alto porque todo lo que accede es referencia, es una estructura fija que gobierna todas las reglas de protección de datos y tiene un puntero oculto al que no se puede acceder ni modificar.

La principal diferencia es que C ++ solo puede brindarle protección de tiempo de comstackción, pero C # le brindará protección incluso en tiempo de ejecución.