Хотя поведение вашей программы не определено в соответствии со стандартом C, ваш код на самом деле правильный в том смысле, что он выполняет именно то, что вы намереваетесь. Он пытается прочитать с адреса памяти 25 и напечатать значение по этому адресу.
Однако в большинстве современных операционных систем, таких как Windows и Linux, программы используют виртуальную память , а не физическую. Память. Поэтому вы, скорее всего, пытаетесь получить доступ к адресу виртуальной памяти, который не сопоставлен с адресом физической памяти. Доступ к несопоставленной ячейке памяти недопустим и вызывает ошибку сегментации.
Поскольку адрес памяти 0 (который обычно записывается в C как 'NULL') обычно резервируется для указания неверного адреса памяти, большинство современных операционных системникогда не отображайте первые несколько килобайт адресов виртуальной памяти на физическую память. Таким образом, ошибка сегментации будет возникать, когда разыменовывается недопустимый указатель NULL (что хорошо, потому что это облегчает обнаружение ошибок).
По этой причине вы можете быть достаточно уверены, что также адрес 25(который очень близок к адресу 0) никогда не сопоставляется с физической памятью и поэтому вызывает ошибку сегментации, если вы пытаетесь получить доступ к этому адресу.
Однако большинство других адресов в адресном пространстве виртуальной памяти вашей программы будет наиболеескорее всего есть такая же проблема. Поскольку операционная система пытается сохранить физическую память, если это возможно, она не отобразит больше адресного пространства виртуальной памяти в физическую память, чем необходимо. Поэтому попытка угадать действительные адреса памяти в большинстве случаев будет неудачной.
Если вы хотите исследовать виртуальное адресное пространство вашего процесса, чтобы найти адреса памяти, которые вы можете прочитать без возникновения ошибки сегментации, вы можетеиспользуйте соответствующий API, предоставляемый вашей операционной системой. В Windows вы можете использовать функцию VirtualQuery () . В Linux вы можете прочитать псевдофайловую систему / proc / self / maps . Сам стандарт C / C ++ не предоставляет никакого способа определения макета адресного пространства виртуальной памяти, поскольку это зависит от операционной системы.
Если вы хотите изучить макет адреса виртуальной памяти других запущенных процессов,затем вы можете использовать функцию VirtualQueryEx () в Windows и читать / proc / [pid] / maps в Linux. Однако, поскольку другие процессы имеют отдельное адресное пространство виртуальной памяти, вы не можете напрямую обращаться к их памяти, но должны использовать функции ReadProcessMemory и WriteProcessMemory в Windows и использовать / proc / [pid] / mem в Linux.
Отказ от ответственности: Конечно, я не рекомендую возиться с памятью других процессов, если вы точно не знаете, что делаете.
Однако, какпрограммист, вы обычно не хотите исследовать адресное пространство виртуальной памяти. Вместо этого вы обычно работаете с памятью, которая была назначена вашей программе операционной системой. Если вы хотите, чтобы операционная система давала вам немного памяти, с которой вы можете читать и записывать по желанию (т.е. без ошибок сегментации), то вы можете просто объявить большой массив символов (байтов) какглобальная переменная, например "char buffer [1024];". Будьте осторожны с объявлением больших массивов в качестве локальных переменных, так как это может вызвать превышение стека . В качестве альтернативы вы можете запросить у операционной системы динамически распределенную память, например, с помощью функции malloc ().