Указатель C / C ++ сохраняет абсолютный адрес памяти, или относительно приложения, или относительно модуля? - PullRequest
10 голосов
/ 25 декабря 2011

Например, если я объявил функцию в основном приложении и передал указатель на нее из динамически загружаемой библиотеки (через dlopen в Linux или LoadLibrary в Windows), используя аргумент полученного символа (черезdlsym или GetProcAddress соответственно) и попытаться вызвать эту функцию, будет ли она работать правильно?

То же самое, если передать указатель из одной динамически загруженной библиотеки в другую?Я думаю, что это должно работать, если указатель, по крайней мере, относительно приложения, но не относительно модуля / библиотеки.

Другой пример.Я объявляю функцию в одном приложении и передаю указатель на нее в другое полностью независимое приложение (как на C, так и на C ++) каким-либо образом (строка параметров или файл ввода-вывода - просто как идея) и пытаюсь вызвать эту функциюработать тоже?Я мог бы ожидать, что это сработает, если указатели будут абсолютными.Может быть, он просто не будет работать, потому что системе вообще не понравится такой перекрестный вызов из-за безопасности?

Ответы [ 4 ]

7 голосов
/ 25 декабря 2011

Это Абсолют .

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

7 голосов
/ 25 декабря 2011

Прежде всего вы должны понимать, что в C и C ++ значение указателя не обязательно должно быть связано с фактически используемыми адресами, если с ним работает арифметика указателя, нулевой указатель имеет значение R, равное 0, и реализациюудается биективно отображать между указателями машины и абстрактными указателями языка.

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

5 голосов
/ 25 декабря 2011

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

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

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

4 голосов
/ 25 декабря 2011

Из-за MMU .Это аппаратный блок в большинстве процессоров для защиты приложений друг от друга.Его основная цель - защитить ядро ​​/ ОС от приложения.Каждое приложение или процесс имеет свою собственную память и не может получить доступ к памяти другого процесса, но должен каким-то образом пройти через ядро ​​/ ОС.

...