Pregunta ¿Cómo sabe dónde está mi valor en la memoria?


Cuando escribo un programa y lo cuento int c=5, pone el valor 5 en un poco de su memoria, pero ¿cómo recuerda cuál? La única forma en que podría pensar sería en tener otro poco de memoria para contarlo, pero luego tendría que recordar dónde se guardaba eso también, entonces, ¿cómo recuerda dónde está todo?


32
2017-09-03 13:19


origen


Respuestas:


Hay muchas buenas respuestas aquí, pero todas parecen pasar por alto un punto importante que creo que fue el principal impulso de la pregunta del OP, así que aquí va. Estoy hablando de lenguajes compilados como C ++, los interpretados son mucho más complejos.

Al compilar su programa, el compilador examina su código para encontrar todas las variables. Algunas variables van a ser globales (o estáticas), y algunas van a ser locales. Para las variables estáticas, les asigna direcciones de memoria fija. Es probable que estas direcciones sean secuenciales y comiencen con algún valor específico. Debido a la segmentación de la memoria en la mayoría de las arquitecturas (y los mecanismos de memoria virtual), cada aplicación puede (potencialmente) usar las mismas direcciones de memoria. Por lo tanto, si suponemos que los programas de espacio de memoria pueden usar comienza en 0 para nuestro ejemplo, cada programa que compile colocará la primera variable global en la ubicación 0. Si esa variable fuera de 4 bytes, la siguiente estaría en la ubicación 4, etc. Esto no entrará en conflicto con otros programas que se ejecutan en su sistema porque en realidad están siendo mapeados a una sección secuencial arbitraria de la memoria en tiempo de ejecución. Es por eso que puede asignar una dirección fija en tiempo de compilación sin preocuparse por golpear a otros programas.

Para las variables locales, en lugar de que se les asigne una dirección fija, se les asigna una dirección fija relativa al puntero de pila (que generalmente es un registro). Cuando se llama a una función que asigna variables en la pila, el puntero de la pila simplemente se mueve por el número requerido de bytes, creando un espacio en los bytes usados ​​en la pila. Todas las variables locales tienen desviaciones fijas asignadas al puntero de la pila que las coloca en esa brecha. Cada vez que se usa una variable local, la dirección de la memoria real se calcula sumando el puntero de pila y el desplazamiento (descuidando los valores de almacenamiento en caché en los registros). Cuando la función retorna, el puntero de la pila se restablece a la forma en que estaba antes de que se llamara a la función, por lo tanto, toda la estructura de la pila, incluidas las variables locales, puede sobrescribirse con la siguiente llamada de función.


9
2017-09-03 16:47



Su código se compila antes de la ejecución, en ese paso su variable será reemplazada por la referencia real del espacio donde se almacenará el valor.

Este al menos es el principio general. En realidad será mucho más completo, pero sigue siendo la misma idea básica.


13
2017-09-03 13:21



leer Variable (programación) - Asignación de memoria:
http://en.wikipedia.org/wiki/Variable_(programming)#Memory_allocation

aquí está el texto del enlace (si no quieres ir allí, pero te faltan todos los enlaces dentro del texto):

Los detalles de la asignación variable   y la representación de sus valores   varían ampliamente, tanto entre programación   idiomas y entre las implementaciones de   un lenguaje dado. Muchos idiomas   implementaciones asignan espacio para   variables locales, cuya extensión dura   para una llamada de función única en la llamada   pila, y cuya memoria es   reclamado automáticamente cuando el   la función vuelve. (Más en general, en   nombre vinculante, el nombre de una variable   está vinculado a la dirección de algunos   bloque particular (secuencia contigua)   de bytes en la memoria y operaciones en   la variable manipula ese bloque.   La referencia es más común para   variables cuyos valores tienen grandes o   tamaños desconocidos cuando el código es   compilado. Tales variables hacen referencia al   ubicación del valor en lugar de   almacenar el valor en sí mismo, que es   asignado desde un grupo de memoria llamado   el montón

Las variables enlazadas tienen valores. Un valor,   sin embargo, es una abstracción, una idea;   en implementación, un valor es   representado por algún objeto de datos, que   se almacena en algún lugar de la computadora   memoria. El programa, o el tiempo de ejecución   ambiente, debe reservar memoria para   cada objeto de datos y, dado que la memoria es   finito, asegúrese de que esta memoria sea   cedido para su reutilización cuando el objeto es   ya no es necesario representar a algunos   el valor de la variable.

Objetos asignados desde el montón   ser reclamado, especialmente cuando   los objetos ya no son necesarios en un   lenguaje recogido de basura (como   C #, Java y Lisp), el tiempo de ejecución   ambiente recupera automáticamente   objetos cuando las variables existentes no pueden   más tiempo se refieren a ellos. En   lenguajes no recogidos de basura, tales   como C, el programa (y el programador)   debe asignar explícitamente la memoria, y   luego más tarde, para liberarla   memoria. El no hacerlo lleva a   pérdidas de memoria, en las que el montón es   agotado mientras el programa se ejecuta, arriesgando   fracaso eventual de agotar   memoria disponible.

Cuando una variable se refiere a una información   estructura creada dinámicamente, algunos de   sus componentes pueden ser solo indirectamente   accedido a través de la variable. De tal   circunstancias, recolectores de basura (o   características análogas del programa en   idiomas que carecen de basura   coleccionistas) deben lidiar con un caso   donde solo una parte de la memoria   alcanzable desde las necesidades variables a   ser reclamado


6
2017-09-03 13:23



Hay un baile de pasos múltiples que gira c = 5 en las instrucciones de la máquina para actualizar una ubicación en la memoria.

  1. El compilador genera código en dos partes. Ahí está la parte de instrucciones (cargar un registro con la dirección de C, cargar un registro con el literal 5, almacenar). Y hay una parte de asignación de datos (deje 4 bytes de espacio en el desplazamiento 0 para una variable conocida como "C").

  2. Un "cargador de enlace" tiene que poner esto en la memoria de forma que el sistema operativo pueda ejecutarlo. El cargador solicita memoria y el sistema operativo asigna algunos bloques de memoria virtual. El sistema operativo también asigna la memoria virtual a la memoria física a través de un conjunto de mecanismos de gestión no relacionados.

  3. El cargador coloca la página de datos en un lugar y la parte de instrucción en otro lugar. Tenga en cuenta que las instrucciones usan direcciones relativas (un desplazamiento de 0 en la página de datos). El cargador proporciona la ubicación real de la página de datos para que las instrucciones puedan resolver la dirección real.

  4. Cuando se ejecuta la instrucción de "almacenamiento" real, el sistema operativo tiene que ver si la página de datos a los que se hace referencia está realmente en la memoria física. Puede estar en el archivo de intercambio y debe cargarse en la memoria física. La dirección virtual que se utiliza se traduce a una dirección física de las ubicaciones de memoria.


6
2017-09-03 13:39



Está integrado en el programa.

Básicamente, cuando un programa se compila en lenguaje de máquina, se convierte en una serie de instrucciones. Algunas instrucciones tienen direcciones de memoria incorporadas, y este es el "final de la cadena", por así decirlo. El compilador decide dónde estará cada variable y quema esta información en el archivo ejecutable. (Recuerde que el compilador es un programa DIFERENTE al programa que está escribiendo; simplemente concéntrese en cómo funciona su propio programa por el momento).

Por ejemplo,

ADD [1A56], 15

podría agregar 15 al valor en la ubicación 1A56. (Esta instrucción sería codificada usando algún código que el procesador entienda, pero no lo explicaré).

Ahora, otras instrucciones le permiten usar una dirección de memoria "variable", una dirección de memoria cargada desde una ubicación. Esta es la base de los indicadores en C. Ciertamente no se puede tener una cadena infinita de estos, de lo contrario se quedaría sin memoria.

Espero que eso aclare las cosas.


4
2017-09-03 13:35



Voy a expresar mi respuesta en términos muy básicos. Por favor, no te insultéis, solo que no estoy seguro de lo competente que eres y quiero darte una respuesta aceptable para alguien que podría ser un principiante total.

En realidad no estás tan lejos en tu suposición. El programa al que ejecuta su código, generalmente llamado compilador (o intérprete, según el idioma), realiza un seguimiento de todas las variables que utiliza. Puede pensar en sus variables como una serie de contenedores, y las piezas individuales de datos se mantienen dentro de estos contenedores. Los contenedores tienen etiquetas, y cuando construyes tu código fuente en un programa que puedes ejecutar, todas las etiquetas se transfieren. El compilador se ocupa de esto por usted, de modo que cuando ejecuta el programa, los elementos correctos se obtienen de su contenedor respectivo.

Las variables que usa son solo otra capa de etiquetas. Esto hace que las cosas sean más fáciles de seguir. La forma en que las variables se almacenan internamente puede tener etiquetas muy complejas o crípticas, pero solo debe preocuparse por cómo se está refiriendo a ellas en su código. Manténgase constante, utilice buenos nombres de variables y realice un seguimiento de lo que está haciendo con sus variables y el compilador / intérprete se encarga de manejar las tareas de bajo nivel asociadas con eso. Este es un caso básico muy simple de uso variable con memoria.


3
2017-09-03 13:51



Deberías estudiar punteros.

http://home.netcom.com/~tjensen/ptr/ch1x.htm


1
2017-09-03 13:21



Reducido al baremo, una búsqueda variable reduce a una dirección que es una compensación estáticamente conocida a un puntero base mantenido en un registro (el puntero de la pila), o es una dirección constante (variable global).

En un lenguaje interpretado, un registro se reserva a menudo para mantener un puntero a una estructura de datos (el "entorno") que asocia los nombres de las variables con sus valores actuales.


1
2017-09-03 13:39