Почему я не могу разыменовать нулевой указатель? То есть, почему я не могу читать / писать память, адрес которой просто 0?
У базового указателя моего процесса есть другой адрес? Если да, есть ли способ получить более низкие сумматоры памяти, доступные для кучи по умолчанию моего процесса?
Нулевой указатель не является указателем на «память [чей] адрес просто 0». Это просто специальный указатель, который не указывает на что-либо действительное.
Язык C говорит, что нет требований к поведению программы, которая разделяет нулевой указатель.
Почему я не могу позвонить по телефону 00000 000 000
? Я должен это сделать.
Страница VM, которая находится по адресу (void *)0x0
или NULL
, по умолчанию не отображается в любой современной ОС, поэтому разыменование указателя NULL
приведет к нарушению сегментации.
Указатели NULL
часто используются в качестве указателей, которые не указывают нигде.
Да, вы можете получить адрес своего текста, стека и кучи. Для стека это относительно просто, для текста и кучи вам нужно будет консультироваться /proc/self/smaps
(если у вас есть procfs
).
Указатель, имеющий значение NULL, должен считаться чем-то, что «указывает на ничего », вместо того, что указывает на некоторый адрес памяти, соответствующий 0.
C 2011 онлайн-проект
6.3.2.3 Указатели
…
3 Целочисленное константное выражение со значением 0 или такое выражение, отлитое от типаvoid *
, называется константой нулевого указателя. 66) Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем , гарантированно сравнится неравномерно с указателем на любой объект или функцию .
66) Макрос
NULL
определяется в(и других заголовках) как константа нулевого указателя; см. 7.19.
Акцент мой. NULL
определяется как недопустимое значение указателя, которое представляет собой четко определенный «нигде». Вы не можете разыгрывать его, потому что нет разницы в разыменовании. Обратите внимание, что хотя константа нулевого указателя всегда 0-значная, значение нулевого указателя необязательно; это может быть 0x00000000
или 0xDEADBEEF
или что-то совершенно другое; это до платформы.
TL; DR, NULL
не представляет адрес 0
; он представляет собой «нет адреса».