¿Cómo se implementa la memoria de solo lectura en C?

7 minutos de lectura

Escuché que en C, si lo hago

char *s = "hello world". 

el “hola mundo” en realidad se almacena en la memoria de solo lectura.

No tengo tan claro lo de la memoria de solo lectura. ¿Cuál es la explicación? ¿Es eso como una bandera para el compilador que le dice al compilador que no escriba en esa sección?

  • Tiene una referencia? Creo que podrías querer decir: const char* s = “hola mundo”.

    – James Negro

    10 de noviembre de 2009 a las 0:29

  • No está claro que todas las arquitecturas de procesador admitan memoria protegida.

    – jldupont

    10 de noviembre de 2009 a las 0:30

  • @James Black: el OP obviamente está hablando del literal de la cadena "hello world"que de hecho se puede almacenar en la memoria de solo lectura, independientemente de cómo se declare el puntero.

    – Ant

    10 de noviembre de 2009 a las 0:36

  • mi referencia es: stackoverflow.com/questions/1704407/…

    usuario188276

    10 de noviembre de 2009 a las 0:40

  • También tengo curiosidad cuando declaramos una constante, ej: const int a; ¿También se asigna a la sección de memoria de solo lectura? (porque es constante, no modificable, así que supongo que sí)

    usuario188276

    10 de noviembre de 2009 a las 0:41

¿Como se implementa la memoria de solo lectura en C
Nils Pipenbrinck

Esa no es una característica del lenguaje C sino una característica del compilador/enlazador y el sistema operativo trabajando juntos.

Cuando compila dicho código, sucede lo siguiente:

  • El compilador colocará la cadena en una sección de datos de solo lectura.

  • El enlazador recopila todos los datos en dichas secciones de solo lectura y los coloca en un solo segmento. Este segmento reside en el archivo ejecutable y está marcado con un atributo de “solo lectura”.

  • Ahora viene el cargador de ejecutables del sistema operativo. Carga el ejecutable (o lo asigna a la memoria para ser más exactos). Una vez hecho esto, el cargador recorre las secciones y establece los permisos de acceso para cada segmento. Para un segmento de datos de solo lectura, lo más probable es que deshabilite la ejecución de código y el acceso de escritura. El código (por ejemplo, sus funciones) obtiene derechos de ejecución pero no acceso de escritura. Los datos ordinarios, como las variables estáticas, obtienen acceso de lectura y escritura, etc.

Así es como lo hacen los sistemas operativos modernos.

Como se dijo, no es una característica del lenguaje C. Si compila el mismo problema para DOS, por ejemplo, el programa se ejecutará pero no será posible la protección contra escritura, porque el cargador de DOS no conoce las secciones de solo lectura.

  • ¿La variable constante también pone la misma sección que “hola mundo”? (Ej: const int a = 6)

    usuario188276

    10 de noviembre de 2009 a las 1:12

  • “Depende”. Lo único que puede decir con seguridad acerca de una const int es que el compilador generará un mensaje de diagnóstico si intenta modificarlo. Puede almacenarse en una sección de solo lectura, o puede que no se almacene nunca y se codifique directamente como una constante en las instrucciones que la utilizan.

    –Mark Bessey

    10 de noviembre de 2009 a las 1:21

  • @tsubasa: probablemente no, y ciertamente no si a es un lugareño. Pero cualquiera que sea la respuesta, también dependerá del sistema operativo y del cargador.

    – Esteban C.

    10 de noviembre de 2009 a las 1:24

  • Además, recuerda, la constante podría incluso subir en una ROM. (En el caso del programa integrado.)

    – Profesor Falken

    10 de noviembre de 2009 a las 9:31

  • @Nils Pipenbrinck ¿Existe alguna posibilidad de hacer cumplir un compilador para poner todo el programa en escribible ¿memoria?

    – phimuemue

    28 de julio de 2011 a las 17:27

Los ejecutables contienen dos partes: una sección .data, que contiene variables globales, y una sección .text, que contiene el código de máquina real.

Las cadenas se colocan en la sección .data. Lo que hace C cuando ve “Hola mundo” es que coloca la cadena “Hola mundo” en el ejecutable mismo y reemplaza la instancia de “Hola mundo” en el programa con la dirección donde termina cargando esa cadena.

Habiendo dicho eso, no estoy seguro de por qué es de solo lectura; en teoría, un programa debería poder modificar su propia memoria.

  • No todos los procesadores y sistemas operativos admiten código automodificable. De hecho, la mayoría de los sistemas operativos modernos contienen protección contra el código automodificable, como característica de seguridad.

    – Crashworks

    10 de noviembre de 2009 a las 0:50

  • Los literales de cadena, debido a que no tienen que ser modificables, pueden y, a menudo, se almacenan en la sección de texto.

    – café

    10 de noviembre de 2009 a las 1:09

La verdadera memoria de solo lectura es implementada por el subsistema de memoria del sistema operativo. El sistema operativo puede marcar ciertas páginas como de solo lectura.

En el binario, el compilador puede decirle al sistema operativo qué partes del ejecutable deben colocarse en páginas de memoria de solo lectura o de lectura y escritura.

  • hmmm… la verdadera protección de la memoria se implementa a nivel del procesador.

    – jldupont

    10 de noviembre de 2009 a las 0:33

  • @jldupont: la protección de la memoria se implementa a nivel de hardware (al menos en x86), pero la configuración inicial la realiza el sistema operativo, es decir, es el sistema operativo el que marcas páginas de solo lectura como tales, y luego el hardware aplica las marcas de solo lectura establecidas por el sistema operativo.

    – Ant

    10 de noviembre de 2009 a las 0:43

  • @AndreyT: por supuesto… mi punto era con respecto a @R Samuel. Sin hardware asistencia, hay mucho que se puede hacer a nivel de software.

    – jldupont

    10 de noviembre de 2009 a las 0:50

  • @R: en realidad, en los sistemas integrados, la memoria de solo lectura podría implementarse utilizando hardware ROM; por ejemplo, utilizando chips EPROM.

    – Esteban C.

    10 de noviembre de 2009 a las 1:28

1647581169 357 ¿Como se implementa la memoria de solo lectura en C
andres cooke

Un ejemplo de cómo hacer esto en Linux está en página 179 de Programación avanzada de Linux por Mark Mitchell, Jeffrey Olham y Alex Samuel.

1647581169 999 ¿Como se implementa la memoria de solo lectura en C
sneha maganahalli

Cuando escribes char s[10]="sneha"; está asignando 10 bytes de espacio de almacenamiento (no memoria, la memoria aparece en la imagen solo cuando está ejecutando su programa) en su archivo de objeto. Esta es una asignación estática de memoria (en tiempo de compilación).

Pero cuando escribes char *s="sneha"; no está asignando ningún espacio de almacenamiento para almacenar "sneha". Se almacenará en la sección de SÓLO LECTURA. Pero el puntero s se almacena en una sección diferente en función de dónde se declare. Pero está apuntando a los DATOS DE SOLO LECTURA "sneha". Entonces, si intenta escribir en él, obtendrá una falla de segmentación.

Por ejemplo:

char *s = "sneha";
s[1] = 'N'; 
printf("%s",s);  // you expecting output sNeha, 
                 // but you get a seg fault since it is READ ONLY DATA 

¿Como se implementa la memoria de solo lectura en C
jared updike

Podrías intentar algo como

s[4] = '0';

y mira si dice “hola mundo” cuando llamas

puts(s);

Si provoca un error de segmentación inmediato o una excepción de prevención de ejecución de datos, probablemente sea de solo lectura. (Si el sistema te permite salirte con la tuya, eso no significa que sea una buena idea).

1647581171 607 ¿Como se implementa la memoria de solo lectura en C
marca bessey

Como han mencionado otras personas, el sistema operativo, el compilador y la arquitectura del chip determinan si el contenido de las cadenas constantes se almacena en la memoria de solo lectura.

Más precisamente, el estándar C especifica que se considera que las cadenas citadas tienen “const char[]” tipo (o palabras en ese sentido, no tengo el estándar a mano).

Cualquier código que intente modificar el contenido de dicha cadena está invocando un comportamiento indefinido. Eso significa que, literalmente, cualquier cosa puede suceder en ese punto, y el proveedor del compilador ni siquiera está obligado a documentar lo que puede suceder.

En la práctica, esto significa que un programa C o C++ que quiera ser portátil debe evitar modificar cadenas constantes.

En general, el compilador no le permitirá modificar el contenido de las variables “const”, por lo que puede considerar que “const” significa “solo lectura” en la mayoría de los casos. Desafortunadamente, hay una excepción especial para char * y const char *, en gran parte por razones históricas. Eso significa que el código como este:

char *x = "Hello, World";
*x = 'h';

se compilará sin errores ni advertencias, aunque invoque un comportamiento indefinido.

¿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