путаница с указателями и виртуальной памятью в C

я думаю, что мой вопрос настолько прост, но я не мог найти ответ на него. исходя из моего понимания виртуальной памяти:

каждый процесс получает непрерывное адресное пространство, которое сопоставляется с физической памятью.

поэтому код, который я пишу в своей программе, должен иметь доступ к любому месту в предоставленной ему виртуальной памяти, поэтому я написал следующий код на C, который выдает исключение типа «исключение нарушения доступа».

Я был бы признателен, если бы кто-нибудь объяснил мне причину.

вот код:

int* a = 1; // pointer to 1st block of memory
*a = 5; // set the content of pointer to 5, but throws exception

person SHM    schedule 25.02.2016    source источник
comment
вы не можете писать в память, которой вы не владеете. Часть адресного пространства зарезервирована (не отображается)   -  person Mitch Wheat    schedule 25.02.2016
comment
Кто сказал, что вся ваша память доступна для записи? Кроме того, почему вы думаете, что он остается непрерывным?   -  person David Schwartz    schedule 25.02.2016
comment
every process receives a contiguous address space which is mapped to physical memory Это вопрос операционной системы, зависящий от ее обработки памяти. following code in C which throws an exception Это вопрос C кода. Стандарт C ничего не знает о конкретной ОС, которую вы, возможно, имеете в виду, и не может решить эту часть. Что касается стандарта C, память, которую вы не получили каким-либо C стандартным способом (например, malloc или определением переменной), не существует для практических целей и вызывает UB (неопределенное поведение) при обращении к ней.   -  person dxiv    schedule 25.02.2016


Ответы (2)


Каждый процесс получает непрерывное ЛОГИЧЕСКОЕ адресное пространство. Не непрерывное ВИРТУАЛЬНОЕ адресное пространство.

Логические СТРАНИЦЫ сопоставляются с физическими КАДРАМИ СТРАНИЦ.

Логическое сопоставление выполняется с использованием ТАБЛИЦЫ СТРАНИЦ, содержащей сопоставления локальных страниц с фреймами страниц.

Однако таблица страниц может не иметь отображения на страничный фрейм для каждой логической страницы.

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

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

Запись в таблице страниц может иметь три состояния:

  1. Это недействительно
  2. Он действителен и сопоставляется с фреймом страницы сопоставления.
  3. Он действителен, но не имеет сопоставления с физическим фреймом страницы. (Опять же, если есть доступ к записи таблицы страниц в этом состоянии, это вызывает ОШИБКУ СТРАНИЦЫ, которая заставляет операционную систему создать сопоставление с действительным фреймом страницы.)

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

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

 int *a = 1 ;

Устанавливает адрес "a" в положение, которое будет на первой странице, что всегда недопустимо.

Ваш

*a = 5 ;

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

person user3344003    schedule 26.02.2016
comment
Разве логический адрес не является синонимом виртуального адреса? В остальном хороший ответ. Было бы еще лучше, если бы вы упомянули, как это связано с подкачкой страниц на диск, когда физической памяти мало. - person Joni; 27.02.2016
comment
Нет, виртуальный и логический — это два связанных, но разных понятия. - person user3344003; 27.02.2016

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

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

person Joni    schedule 25.02.2016
comment
какие его части? у вас есть ссылка для получения дополнительной информации? - person SHM; 25.02.2016
comment
Поиск сопоставлений адресов зависит от ОС. Например, ядро ​​Linux предоставляет эту информацию в файле /proc/self/maps. - person Joni; 25.02.2016