Сегмент памяти "только для чтения" в с++

Что из себя представляет сегмент памяти "только для чтения" и какие данные туда попадают?


Ответы (1 шт):

Автор решения: nick_n_a

С точки зрения программ.

Сегмент памяти "только для чтения" (readonly) - туда попадают как правило константы. Информация о классе так же считается константой - виртуальные таблицы, typeinfo и тому подобное. "Сегмент" - это больше понятие для линкера. Это сигнал линкеру что эти данные нужно поместить в секцию для чтения. Так же в этот сегмент попадают разные служебные данные, которые заложил разработчик компилятора. Некоторые компиляторы оставляют там свою сигнатуру (подпись).

Попадёт ли константа в этот сегмент - не обязательно. Если мы создаём константу - то она может не существовать явно - т.е. она просто в сегменте кода. a) Если мы пишем const int a= 1; то под а может вообще не быть зарезервировано место в сегменте. Значение будет поставлено непосредственно в коде. б) Добавим f(&a) ссылку на константу. Если компилятор не смог упростить код, то что бы получить адрес константы - её прийдётся куда-то записать. Тогда компилятор поместит её в сегмент чтения. в) стандартом не гарантировано что все константы должны быть в сегменте только чтение. Если компилятору не удалось поместить константу в сегмент только чтение, то он может её разместить в стеке, где не будет readonly.

После компилятора, программу обрабатывает линкер. Куда именно будет помещён сегмент readonly - зависит так же от линкера. Я встречал что програмный код и константы некоторые компиляторы/линкеры объеденяют. Поэтому если нужна более точная информация о размещении - то каждую отдельную версию компилятора нужно смотреть по-факту.

С апаратной точки зрения. Существуют разные платформы. Часть платформ поддерживает выделения страницы памяти readonly, а часть нет. Readonly будет работать только если платформа поддерживает эту опцию. В x86 размер странины бывает 4к как правило. Современные ПК могут иметь размер страницы больше. Сегмент readonly может быть размещён на одной или нескольких страницах подрят (т.е. память скорее всего будет выделена с избытком). Многие современные микроконтроллеры так же поддерживают защиту страниц памяти от записи, например stm32.

Для windows статус страницы памяти можно проверить функциями VirtualQuery,IsBadCodePtr,IsBadReadPtr,IsBadStringPtrA,IsBadStringPtrW``IsBadWritePtr.

Куда компилятор поместил ту или иную переменную можно узнать в детальном map-файле.

→ Ссылка