Porque es una dirección virtual, no física.
Cada proceso obtiene su propio espacio de direcciones (por ejemplo, un sistema de 32 bits puede permitir que cada proceso tenga su propio espacio de direcciones con el rango 4G completo).
Es la unidad de gestión de memoria que asignará las direcciones virtuales a las físicas (y manejará cosas como fallas de página si las páginas intercambiadas deben comprarse desde el almacenamiento secundario).
El siguiente diagrama puede ayudar, cada sección que representa un bloque de 4K de memoria:
Process A Physical Memory Process B
+-------+ +-------------+ +-------+
0K | |----> 0K | (shared) | <----| | 0K
+-------+ +-------------+ +-------+
4K | |--+ 4K | | <----| | 4K
+-------+ | +-------------+ +-------+
8K | | +-> 8K | | | | 8K
+-------+ +-------------+ +-------+
| : : : : : : : |
| +-------------+ |
| 128K | | <--------+
| +-------------+
+--------> 132K | |
+-------------+
se puede ver, en ese diagrama, la desconexión entre direcciones de memoria virtual y direcciones de memoria física (y la posibilidad de que procesos para compartir bloques de memoria también). Las direcciones en los lados izquierdo y derecho son direcciones virtuales que ven los procesos.
Las direcciones en el bloque central son direcciones físicas reales donde los datos son "realmente" y la MMU maneja la asignación. Para obtener una explicación más detallada de fork
(y exec
), también puede consultar this answer.
También tenga en cuenta que tiene que ser así. Si la dirección de 'y' sí cambió, cualquier apuntador (dirección) retenido en variables o estructuras antes de la bifurcación ya no sería correcto después de la bifurcación. Eso haría que el fork sea mucho menos útil, ya que el proceso secundario no podría acceder a ninguna estructura de datos (listas vinculadas, árboles) o datos asignados dinámicamente desde antes, ya que esas cosas dependen de punteros. Los sistemas sin memoria virtual prácticamente no pueden implementar fork, en su lugar obtiene vfork (http://pubs.opengroup.org/onlinepubs/7908799/xsh/vfork.html). –
No técnicamente "tiene que ser así": podría usar punteros doblemente indirectos siempre que su tiempo de ejecución de C sea compatible (en otras palabras, un puntero es un desplazamiento desde un valor conocido y, al bifurcar, mueve los datos a otro lugar para el niño y ajustar el valor conocido). Sin embargo, sería un asesino de rendimiento. Creo que Windows en modo real hizo algo similar a esto con el bloqueo y desbloqueo de la memoria. – paxdiablo
Bastante justo, usted básicamente ha descrito una implementación de software barata y alegre (o costosa y miserable, según cómo la mire) de la memoria virtual. En ese caso, aún verá lo que observa el interrogador, que la dirección anterior y posterior a la horquilla se imprime con el mismo valor. A menos que el formateador de impresión '% p' también se haya agregado a la dirección base, supongo que :-) –