Это поведение не определяется стандартом C. В любой многопользовательской операционной системе общего назначения каждому процессу предоставляется свое собственное виртуальное адресное пространство. Вся память, выделенная для процесса, отделена от памяти, выделенной другим процессам, за исключением определенной общей памяти:
- Данные, доступные только для чтения, могут совместно использоваться процессами, особенно инструкции и постоянные данные двух процессы запускают один и тот же исполняемый файл и инструкции и постоянные данные общих библиотек. Эти данные могут иметь один и тот же адрес в разных процессах или по разным адресам (в зависимости от различных факторов, в том числе от того, является ли код независимым от позиции и используется ли рандомизация размещения адресного пространства).
- Некоторые операционные системы также отображают систему общие данные в процессы по умолчанию.
- Память может быть распределена между процессами путем явного запроса этих процессов для сопоставления сегментов общей памяти. Эти сегменты могут появляться или не появляться по одному и тому же виртуальному адресу в разных процессах. (Запрос на сопоставление совместно используемой памяти может запросить определенный адрес, и в этом случае разные процессы могут организовать использование одного и того же адреса, или это может позволить программному обеспечению отображения выбрать адрес, и в этом случае разные процессы не могут полагаться на получение одного и того же назначения адреса. .)
В специальной операционной системе разные процессы могут совместно использовать одно адресное пространство.
Дополнение
Это неправильный код:
int *i;
*i = 10;
Объявление int *i;
определяет i
как указатель, но не присваивает ему значение. Тогда использование *i
нецелесообразно, поскольку оно пытается сослаться на то, куда указывает i
, но i
не было назначено указывать на что-либо.
Чтобы определить int
и сделать его адрес видимым в вы можете определить int i;
и затем напечатать &i
.
. Это неправильный способ печати адреса:
printf("%lld", i);
Чтобы напечатать адрес, приведите его к void *
и отформатируйте его %p
. Результат форматирования определяется реализацией:
printf("%p", (void *) &i);
Это неправильный способ восстановления адреса:
int *t;
t = (int*)atoll(argv[1]);
Как и в случае printf
, тип должен быть void *
, и возникают проблемы при попытке преобразования с atoll
. Стандарт C не гарантирует, что он будет работать; формат, полученный при печати с %p
, может не быть обычным целочисленным форматом. Вместо этого используйте спецификатор %p
с sscanf
:
void *temp;
if (1 != sscanf(argv[1], "%p", &temp))
exit(EXIT_FAILURE);
int *t = temp;
Когда адрес исходит из другого процесса, поведение преобразования sscanf
не определяется стандартом C.