Почему адрес переменной дочернего процесса и родительского процесса одинаков

вот мой код

int main()
{
  pid_t pid;
  int y = 3;  
  if ( (pid = fork()) <0 )
   return -1;;

  if( pid == 0 )  /* child */
  {
    printf(" before: %d %pn", y, &y );
    y *= 10;
    printf("after: %d %pn", y, &y );
  }
  else /* father */
  {
   sleep(1);
   printf("father: %d %pn" , y , &y );

  }
  return 0;
}

вывод программы выглядит следующим образом:

before: 3 ffbff440
after: 30 ffbff440
father: 3 ffbff440

мой вопрос в том, почему адрес переменной дочернего и родительского одинаков, но значение отличается?

2 ответов


потому что это виртуальный адрес, а не физический.

каждый процесс получает свое собственное адресное пространство (например, 32-разрядная система может позволить каждому процессу иметь свое собственное адресное пространство с полным диапазоном 4G).

это блок управления памятью, который будет сопоставлять виртуальные адреса с физическими (и обрабатывать такие вещи, как ошибки страниц, если замененные страницы должны быть выкуплены из вторичного хранилища).

следующая диаграмма может помочь, каждый раздел, представляющий блок памяти 4K:

   Process A           Physical Memory      Process B
   +-------+           +-------------+      +-------+
0K |       |---->   0K |  (shared)   | <----|       | 0K
   +-------+           +-------------+      +-------+
4K |       |--+     4K |             | <----|       | 4K
   +-------+  |        +-------------+      +-------+
8K |       |  +->   8K |             |      |       | 8K
   +-------+           +-------------+      +-------+
       |                : : : : : : :           |
       |               +-------------+          |
       |          128K |             | <--------+
       |               +-------------+
       +--------> 132K |             |
                       +-------------+

вы можете видеть на этой диаграмме разъединение между адресами виртуальной памяти и адресами физической памяти (и возможность для процессов совместно использовать блоки памяти). Адреса слева и справа-это виртуальные адреса, которые видят процессы.

адреса в центральном блоке являются фактическими физическими адресами, где данные "действительно" есть, и MMU обрабатывает отображение.

для более глубокого объяснения forkexec), вы также можете посмотреть ответ.


адрес "такой же", как у каждого процесса есть собственное виртуальное адресное пространство, и переменная обычно загружается в одно и то же место. Обратите внимание, что это не физический адрес в памяти. Также обратите внимание, что существуют схемы, которые преднамеренно рандомизируют местоположение, в котором загружается процесс, чтобы затруднить атаку/взлом процесса. В таком случае адрес будет другим.