Wenn ich zum Beispiel eine Funktion in der Hauptanwendung deklariere und einen Zeiger darauf übergebe, von einer dynamisch geladenen Bibliothek (über dlopen
unter Linux oder LoadLibrary
unter Windows) unter Verwendung eines erhaltenen Symbolarguments (über dlsym
bzw. GetProcAddress
) und versuchen, diese Funktion aufzurufen, würde es richtig funktionieren?
Gleiches, wenn der Zeiger von einer dynamisch geladenen Bibliothek zu einer anderen weitergegeben wird? Ich denke, es sollte funktionieren, wenn Zeiger mindestens relativ zur Anwendung, aber nicht relativ zu Modul / Bibliothek.
Ein anderes Beispiel. Ich deklariere eine Funktion in einer Anwendung und übergeben Zeiger auf eine andere vollständig unabhängige Anwendung (sowohl C und C ++) irgendwie (Parameter-String oder Datei-i / o-idk wie, nur eine Idee) und versuchen, diese Funktion aufzurufen, würde es Arbeit auch? Ich könnte erwarten, dass es funktioniert, wenn die Zeiger absolut sind. Vielleicht wird es einfach nicht funktionieren, weil das System aus Sicherheitsgründen überhaupt keinen solchen Querruf wünscht?
Zuerst müssen Sie verstehen, dass in C und C ++ der Wert eines Zeigers nicht mit den tatsächlich verwendeten Adressen in Beziehung stehen muss, solange die Zeigerarithmetik damit arbeitet, der Nullzeiger einen R-Wert von 0 und die Implementierung hat schafft es, bijektiv zwischen Maschinenzeigern und Sprachzusammenfassungszeigern zu mappen.
Auf modernen Systemen sehen Prozesse einen virtuellen Adressraum und jeder Prozess hat seinen eigenen Adressraum. Bibliotheken können an jede Adresse geladen werden, so dass ein Zeiger zwischen Prozessen übergeben wird, ist völliger Unsinn - zumindest bei ausgelagerten Speicherarchitekturen. Innerhalb einer Prozess-Maschinen-Ebene werden jedoch Zeiger ohne Probleme zwischen geladenen Bibliotheken übergeben; immerhin teilen sie sich den gleichen Adressraum. Auf der Sprachebene sind sie möglicherweise nicht identisch (obwohl sie normalerweise identisch sind), wenn mehrere Sprachen miteinander in Kontakt kommen. Aber Kompilierungseinheiten, die mit demselben Compiler erstellt wurden, verwenden dieselbe Pointer-Semantik. Auch die meisten Sprachimplementierungen, die auf die native Maschine abzielen, stimmen der Pointer-Semantik aus dem einfachen Grund zu, dass die Konvertierung zwischen Zeigerformaten einen enormen Leistungseinbruch erzeugen würde.
Es ist absolut .
Die Tatsache, dass es eine virtuelle Adresse ist, hat damit nichts zu tun - es ist eine absolute virtuelle Adresse. Es macht keinen Unterschied zu Ihrem Programm, ob es virtuellen Speicher oder physischen Speicher verwendet ... Sie sollten sich nicht damit beschäftigen, es sei denn, Sie übergeben Zeiger zwischen Prozessen (die Ich bezweifle ernsthaft, dass du es bist, oder es sei denn, du schreibst Kernel-Code auf niedriger Ebene oder mappst / entpacke Seiten manuell (was ich auch bezweifle, dass du es bist).
Auf verschiedenen Betriebssystemen funktioniert das anders. Auf älteren / eingebetteten Betriebssystemen haben alle Prozesse den gleichen Platz - ein Prozess kann Dinge leicht für einen anderen verwirren.
Bei den meisten modernen (d.h. nicht eingebetteten) modernen Betriebssystemen hat jeder Prozess einen separaten Adressraum. Alle Adressen sind relativ zu diesem Raum. Es spielt keine Rolle, wie Dinge miteinander kompiliert / verknüpft werden. Wenn sie im selben Prozess sind teilen sie sich den Adressraum.
Daraus folgt, dass zwei verschiedene Prozesse keine impliziten Möglichkeiten haben, auf jeden anderen Raum zuzugreifen.
Ist wegen MMU . Es ist eine Hardwareeinheit in den meisten Prozessoren zum Schutz von Anwendungen voneinander. Sein Hauptzweck ist es, Kernel / OS vor Anwendungen zu schützen. Jede Anwendung oder jeder Prozess hat seinen eigenen Speicher und kann nicht auf Speicher anderer Prozesse zugreifen, sondern muss in irgendeiner Weise durch Kernel / OS gehen.
Tags und Links c++ pointers memory-address