verificar revista lecturas horas home gubernamental etica ethos certificacion cdpe acceso c string literals

lecturas - revista ethos



Alcance de los literales(de cadena) (7)

De hecho, devuelve un puntero a la cadena terminada en cero almacenada en la sección de datos del ejecutable, un área cargada al cargar el programa. Solo evite intentar cambiar los personajes, podría dar resultados impredecibles ...

Siempre trato de evitar devolver literales de cadena, porque me temo que no están definidos fuera de la función. Pero no estoy seguro si este es el caso. Tomemos, por ejemplo, esta función:

const char * return_a_string(void) { return "blah"; }

Es este código correcto? Funciona para mí, pero tal vez solo funciona para mi compilador (gcc). Entonces, la pregunta es, ¿los literales (de cadena) tienen un alcance o están presentes / definidos todo el tiempo?


Es realmente importante tomar nota de los resultados indefinidos que Brian mencionó. Como ha declarado que la función devuelve un tipo const char *, debería estar bien, pero en muchas plataformas los literales de cadena se colocan en un segmento de solo lectura en el ejecutable (generalmente el segmento de texto) y modificarlos causará una infracción de acceso. en la mayoría de las plataformas.


Este código está bien en todas las plataformas. La cadena se compila en el binario como un literal de cadena estática. Si está en Windows, por ejemplo, incluso puede abrir su .exe con el bloc de notas y buscar la cadena en sí.

Como es un alcance literal de cadena estática, no importa.

Agrupación de cadenas:

Una cosa a tener en cuenta es que, en algunos casos, los literales de cadena idénticos se pueden "agrupar" para ahorrar espacio en el archivo ejecutable. En este caso, cada literal de cadena que sea el mismo podría tener la misma dirección de memoria. Sin embargo, nunca debes asumir que será o no será el caso.

En la mayoría de los compiladores puede establecer si usar o no el agrupamiento de cadenas estáticas para mezclar literales.

Tamaño máximo de literales de cadena:

Varios compiladores tienen un tamaño máximo para el literal de cadena. Por ejemplo, con VC ++ esto es aproximadamente 2.048 bytes.

La modificación de un literal de cadena proporciona un comportamiento indefinido:

La modificación de una cadena literal nunca debería hacerse. Tiene un comportamiento indefinido.

char * sz = "this is a test"; sz[0] = ''T''; //<--- undefined results

Literales de cadena ancha:

Todo lo anterior se aplica igualmente a los literales de cadenas anchas.

Ejemplo: L "este es un literal de cadena ancha";

Los estados estándar de C ++: (sección lex.string)

1 Un literal de cadena es una secuencia de caracteres (como se define en lex.ccon ) rodeada de comillas dobles, comenzando opcionalmente con la letra L, como en "..." o L "...". Un literal de cadena que no comienza con L es un literal de cadena ordinario, también conocido como literal de cadena estrecha. Un literal de cadena ordinaria tiene el tipo "array of n const char" y la duración de almacenamiento estático ( basic.stc ), donde n es el tamaño de la cadena como se define a continuación, y se inicializa con los caracteres especificados. Un literal de cadena que comienza con L, como L "asdf", es un literal de cadena ancha. Un literal de cadena ancha tiene el tipo "array of n const wchar_t" y tiene una duración de almacenamiento estática, donde n es el tamaño de la cadena como se define a continuación, y se inicializa con los caracteres especificados.

2 Si todos los literales de cadena son distintos (es decir, se almacenan en objetos no superpuestos) está definido por la implementación. El efecto de intentar modificar un literal de cadena no está definido.


Esto es válido en C (o C ++), como otros han explicado.

Lo único que puedo pensar en tener en cuenta es que si está usando dlls, entonces el puntero no será válido si el dll que contiene este código está descargado.

El estándar C (o C ++) no comprende ni tiene en cuenta el código de carga y descarga en tiempo de ejecución, por lo que cualquier cosa que lo haga se enfrentará a consecuencias definidas por la implementación: en este caso la consecuencia es que el literal de cadena, que se supone tiene duración de almacenamiento estático, aparece desde el Punto de vista del código de llamada para no persistir durante toda la duración del programa.


No, los literales de cadenas no tienen alcance, por lo que se garantiza que su código funcionará en todas las plataformas y compiladores. Se almacenan en la imagen binaria de tu programa, por lo que siempre puedes acceder a ellos. Sin embargo, tratar de escribirles (descartando la const ) conducirá a un comportamiento indefinido.


Si está bien. Viven en una tabla de cadenas global.


Te doy un ejemplo para que tu confusión se vuelva algo clara

char *f() { char a[]="SUMIT"; return a; }

esto no funcionará

pero

char *f() { char *a="SUMIT"; return a; }

esto funciona.

Motivo: "SUMIT" es un literal que tiene un alcance global. mientras que la matriz que es solo una secuencia de caracteres {''S'', ''U'', ''M'', ''I'', "T '''' / 0 ''} tiene un alcance limitado y desaparece tan pronto como se devuelve el programa.

Espero que esto ayude