Почему адрес переменной дочернего процесса и родительского процесса совпадают - PullRequest
8 голосов
/ 31 августа 2011

Вот мой код

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

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

  }
  return 0;
}

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

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

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

Ответы [ 2 ]

25 голосов
/ 31 августа 2011

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

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

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

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

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

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

Адреса в центральном блоке являются фактическими физическими адресами, где данные «действительно» находятся, а MMU обрабатывает сопоставление.

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

1 голос
/ 31 августа 2011

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

...