2012-10-09 37 views
6

Descargo de responsabilidad: soy nuevo en C/C++.¿Puedo acceder a cualquier cosa en la memoria?

Si tuviera que manually assign a memory address a una variable en C, y luego tratar de hacer eco a cabo ese valor ... ¿tengo acceso restringido para ver nada en la memoria o hay restricciones en su lugar?

Por ejemplo:

char * p = (char *)0x28ff44; 
printf("Memory value: %c", *p); 

supongo que eso fallará estrepitosamente si lo que estaba en esa dirección no se ajusta al tamaño de tipo char, pero es simplemente un ejemplo. Lo que realmente me interesa es si algo como esto es posible o los sistemas operativos imponen restricciones y solo te permiten acceder a la memoria en tu espacio de memoria dado.

+1

Puede encontrar información interesante en otra pregunta sobre el desbordamiento de la pila: http://superuser.com/questions/189876/how-os-detects-memory-access-violations – fycth

+0

Wow, gracias por todas las excelentes respuestas. Recuerdo que traté de aprender C en la escuela secundaria (hace más de 10 años, supongo) y me parece recordar que, en el momento en que estaba incursionando, generalmente había un espacio en la memoria y podían ocurrir problemas dentro de él. Es bueno ver que ahora hay más protección para los noobs de bajo nivel como yo. –

+1

Nota al margen, '% s' es la cadena de formato incorrecta para un solo carácter, necesita'% c';) – slugonamission

Respuesta

5

Oh mi, bueno.

Técnicamente, sí, puedes. En los dispositivos integrados que no usan una MMU ni ninguna forma de protección (o, ya sabes, x86 en modo real), puede hacer exactamente lo que ha publicado allí. También puede hacerlo en modo de usuario en cualquier sistema operativo, pero las posibilidades de que llegue a la memoria válida son muy pequeñas.

En realidad, no, no puedes hacer eso. Dada la memoria virtual y la protección de memoria, es muy probable que la región a la que intenta acceder no se haya mapeado y, por lo tanto, fallará. Además, si accedes a la memoria protegida (por ejemplo, cualquier cosa que pertenezca al sistema operativo), tu acceso fallará. Ambos escenarios son los que causan fallas de segmentación.

Su resumen es válido (para diversas definiciones de válido), y el programa intentará acceder a la memoria solicitada. Es solo que en realidad podría no asignarse a nada.

También vale la pena señalar que así es como funciona la asignación de memoria de E/S. Digamos que tengo un registro de control de hardware que, cuando se escribe, escribe un byte sobre la línea serial/UART adjunta (y, por simplicidad, funciona como magia y no necesita ningún otro registro para establecer). En C, esto se escribiría de la siguiente manera para mi dispositivo excesivamente simplificada:

#define UART1_OUT 0xFC56 

volatile char* uart = UART1_OUT; // Definition of pointer to variable. 
            // volatile is required here. Look it up, but 
            // it basically stops your compiler optimising 
            // anything to do with this variable 

*uart = 'A';      // Write an A character to the serial line 

Por supuesto, los dispositivos del mundo real son un poco más compleja;).

+0

Supongo que debe escribir el valor de la dirección, de lo contrario, el compilador dará un error. –

+0

No, es una advertencia por defecto en GCC. No estoy seguro acerca de Visual C y Clang. – slugonamission

2

Esto depende de la arquitectura de la computadora y del sistema operativo en el que se ejecute el programa. Los sistemas operativos modernos tienen el concepto de memoria protected y virtual. Con la memoria virtual, las direcciones de memoria no se refieren a la memoria física, sino a un espacio de memoria virtual asignado a la aplicación actual. Intentar leer o escribir en la memoria fuera del espacio de memoria asignado en estos casos llevará a un error del programa (generalmente un error de segmentación, o falla de protección).

+0

Entonces, ¿algunos SO permiten este tipo de intrusión flagrante en el espacio de memoria de otras aplicaciones y/o el sistema operativo en sí? –

+0

http://en.wikipedia.org/wiki/Memory_protection – wroniasty

+0

Ah ok. Entonces, con la memoria virtual, ¿no podría "accidentalmente" bloquear otros programas o el sistema operativo? –

1

Es muy probable que los sistemas con una Unidad de administración de memoria (MMU) no le permitan acceder a la memoria arbitraria. Cualquier sistema operativo moderno usa protección de memoria. Pero en el sector incrustado hay muchos sistemas operativos que no emplean protección de memoria y donde de hecho es posible acceder a cualquier memoria direccionable.

1

Si tuviera que asignar manualmente una dirección de memoria a una variable en C, y luego tratar de eco de que el valor ... ¿tengo acceso sin restricciones a ver nada en la memoria o hay restricciones en su lugar ?

El lenguaje C se complace en permitir que lo intente, pero la mayoría de los sistemas operativos no le permiten acceder a la memoria fuera del espacio de memoria de su proceso. Si está escribiendo código para un sistema integrado donde no hay mucho entre su código y el hardware, probablemente podrá leer y escribir en cualquier ubicación que desee. Sin embargo, si está escribiendo código para un sistema con memoria protegida, no tanto.

supongo que eso fallará estrepitosamente si lo que estaba en esa dirección no se ajuste al tamaño de tipo char

nah ... el compilador no le importa qué tipo de datos se almacena en cualquier dirección dada. Cuando dice (char *)0x28ff44, le dice que 0x28ff44 es char *, y eso es suficiente para el compilador. Sin embargo, su código aún puede bloquearse por otros motivos, como si 0x28ff44 no es una dirección válida.

Cuestiones relacionadas