Почему одна и та же переменная получила разные виртуальные адреса при разных запусках?

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

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    int node=0;
    char* buffer;
    int i;
    printf("Hello World from Node %d the vm of i is %p and %ld \n",node, &i,&i);
    buffer = (char*)malloc(sizeof(char)*1024*1024*300); 
    for(i = 0; i < 1024*1024*300; i++){
    buffer[i] = (char)1;
}   
printf("I  am in %d and the vm of buffer is %p:%ld \n",node, buffer,buffer);
return 0;
}

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

-bash-4.0$ gcc singletest.c
-bash-4.0$ ./a.out 
Hello World from Node 0 the vm of i is 0x7fffb87a8e00 and 140736288427520 
I  am in 0 and the vm of buffer is 0x7fb05dfcf010:140395467829264 
-bash-4.0$ ./a.out 
Hello World from Node 0 the vm of i is 0x7fffec2856f0 and 140737155454704 
I  am in 0 and the vm of buffer is 0x7f5888c54010:140018228477968 
-bash-4.0$ ./a.out 
Hello World from Node 0 the vm of i is 0x7fff1f44a780 and 140733717981056 
I  am in 0 and the vm of buffer is 0x7fbea3b91010:140456767328272 

Я также написал простой код MPI, в котором каждый процесс просто генерирует одну и ту же переменную. И одна и та же переменная для разных процессов имеет разные значения указателя, что не так, как я ожидал.

Кто-нибудь может мне это объяснить ? Спасибо,


person Hui Jin    schedule 24.06.2011    source источник


Ответы (2)


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

В частности, в вашем случае переменная, на которую вы смотрите, представляет собой указатель, выделенный в куче. Нет абсолютно никаких оснований ожидать, что двойное выделение памяти в куче приведет к тому, что один и тот же адрес будет получен дважды.

person Ori Pessach    schedule 24.06.2011
comment
Спасибо! Если рандомизация адресов отключена, как вы думаете, возможно ли, что у меня будет одно и то же значение указателя для двух прогонов? Даже для переменной кучи? Спасибо, - person Hui Jin; 25.06.2011
comment
Я серьезно сомневаюсь, что вы можете положиться на это. Я бы не рекомендовал это. - person Ori Pessach; 25.06.2011
comment
Я просто следую инструкциям на stackoverflow.com/ вопросов/1921485/, чтобы отключить рандомизацию. Переменная кучи имеет фиксированный виртуальный адрес для разных запусков. - person Hui Jin; 25.06.2011
comment
Причина, по которой я спрашиваю, заключается в том, что вы действительно не можете полагаться на такое поведение. - person Ori Pessach; 25.06.2011

Этот вопрос похож на один из моих: псевдо-случайный указатель стека в Linux?

Все это сделано из соображений безопасности, как описано в ссылке в awser.

person Richard Pennington    schedule 24.06.2011
comment
о да, рандомизация адресного пространства отвечает на мои вопросы. Спасибо! - person Hui Jin; 25.06.2011