Есть ли физическая часть памяти с адресом NULL (0)? - PullRequest
3 голосов
/ 14 октября 2010

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

Ответы [ 7 ]

6 голосов
/ 14 октября 2010

Физический адрес всегда равен 0 (но он может не обязательно отображаться в физическую память), но на типичной платформе любой доступ будет обычно осуществляться в виртуальном адресном пространстве (как jweyrich указывает ниже, вы можете использовать mmap и т. Д. Для непосредственного сопоставления физического адресного пространства), поэтому любая попытка чтения / записи по адресу 0 вызовет какое-то исключение.

На более простых процессорах (например, микроконтроллерах и т. Д.) Такой защиты может не быть, поэтому, если вы попытаетесь выполнить запись по адресу 0, вам будет нечего ловить.

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

3 голосов
/ 14 октября 2010

Да, у компьютеров может быть физический адрес 0. Например, в старые времена DOS вы регулярно туда ходили - вот где начиналась таблица прерываний - поэтому, если вы хотите знать, что будет работать при нажатии клавиши илитаймер прерывания, тогда вы можете создать указатель на массив указателей и указать , что на 0. Я пересмотрел формулировку в Стандарте C ++ пару лет назад, чтобы убедиться, что это обязательно неопределенное поведение в системе, гдеадрес 0 должен быть доступен (на уровне ЦП / архитектуры), и я помню, что он не был явным, говоря, что это может привести к неопределенному поведению.Тем не менее, он в основном оставляет за собой право загружать значение, отличное от 0, когда вы помещаете 0 в указатель, сравниваете указатель с 0 и т. Д.: 0 - это специальное значение часового, с которым он может делать все, что ему нравится, поэтому, если вы хотите идти«По книге», тогда вам придется ходить вокруг.

3 голосов
/ 14 октября 2010

Да, во многих системах (особенно встроенных) имеется адрес памяти 0, который является допустимым для чтения и записи.

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

1 голос
/ 14 октября 2010

Поскольку это тег C ++, следует отметить, что Стандарт гарантирует, что попытка доступа к «нулевому указателю» с помощью разыменования вызывает неопределенное поведение:

1.9 Выполнение программы [intro.execution]

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

... что результатом неудачного dynamic_cast является нулевой указатель, что delete нулевой указатель не имеет никакого эффекта, и, наконец, "константа нулевого указателя" есть == целочисленное выражение 0:

4.10 Преобразование указателя [conv.ptr]

  1. Константа нулевого указателя является целочисленным выражением константы (5.19) rзначением целочисленного типакоторый оценивается в ноль.
1 голос
/ 14 октября 2010

Обратите внимание, что даже если значение 0 сравнивается с нулевым указателем C / C ++, в стандарте не гарантируется, что нулевой указатель фактически ссылается на нулевой адрес в (виртуальном) адресном пространстве процесса. (Обычно так и есть, но вы знаете, что там обязательно должны быть какие-то микроконтроллеры и т. Д.) Так что *(reinterpret_cast<int *>(&my_pointer)) не может == 0.

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

1 голос
/ 14 октября 2010

В пространстве ядра да NULL может быть допустимым адресом.В пользовательском пространстве нет.Что касается физического адреса, то да, всегда есть адрес ноль, но программы работают с логическими адресами.

1 голос
/ 14 октября 2010

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

...