Hallo, Die Anweisung "int* ptr = 0x30000" funktioniert nicht. Kann mir jemand sagen wie ich einem Pointer (in C/C++) eine Adresse dirket zuweise, ohne "ptr = &variable" zu benutzen? Ich habe nur den Adresswert, aber nicht "variable" zur Verfügung... Danke.
Im Zweifelsfall kann man in C und C++ den Compiler immer mit einem Cast zu etwas zwingen: int* ptr = (int*)0x30000; Man muss dann nur sselbst die Verantwortung dafür übernehmen, dass das eine sinnvolle Operation ist.
Musst das Literal 0x30000 casten, da es ein int oder ein long ist: Irgendwie so: int* ptr = (int *)0x30000;
Kommt drauf an in was für einer Umgebung dein Programm laufen soll. Wenn es innerhalb eines Betriebssystemes läuft wird diese Zuweisung zu einem Fehler führen. Speicherbereiche müssen erst in deine Application reingemapt werden. Dies dient dem Schutz des Betriebssystemes damit nicht "ausversehn" etwas an eine Stelle geschrieben wird, wo der Wert nichts zu suchen hätte.
Stefan Kunz wrote: > Wenn es innerhalb eines Betriebssystemes läuft wird diese Zuweisung > zu einem Fehler führen. Nein.
@Peter Also eine kleine Erklärung könnte es schon sein. Vielleicht etwas zu verallgemeinert, aber Betriebssysteme, die eine MMU brauchen (QNX oder Linux z.B.), müssen physicalischen Speicher erst in ihren virtuellen Speicherbereich mappen, damit darauf zugegriffen werden kann. Somit sind solche Zuweisungen nur bedingt möglich, z.B. wenn das Zielsystem keine MMU besitzt. MfG Stefan Kunz
"ptr" liegt im gueltigen Speicherbereich, worauf er zeigt/zeigen wird ist bei der Zuweisung irrelevant. In den hier gezeigten Beispielen findet keine Dereferenzierung dieses Pointers statt. Auch sonst ist deine Erklaerung eher irrefuehrend, als hilfreich. Auch auf Systemen ohne MMU kann der Zugriff auf nicht existenden Speicher zu "Abstuerzen" fuehren. Und andersrum muss es auf Systemen mit MMU nicht zu "Abstuerzen" fuehren, das ist eine Frage der Implementation.
Es ist letztlich vollkommen wurscht, ob an '0x30000' irgendetwas Brauchbares zu finden ist. Es ist überdies auch vollkommen unbestimmt, wo '0x30000' im Speicher liegt. C verlangt lediglich, dass ein Zeiger mittels irgendeiner Funktion auf eine Ganzzahl abgebildet werden kann, und dass diese (irgendeine) Funktion umkehrbar ist, man also von der Ganzzahl wieder zum korrekten Zeiger kommt. Diese Ganzzahl muss überhaupt nichts mit Speicheradressen zu tun haben. Wichtig könnte es sein, das Literal zu casten, damits passt, z.B. in der Art:
1 | int *p = 0x30000UL; |
Das gibt dann evtl. einen Typenfehler, den man mit dem (int *)-Cast erschlägt. Zulässig ist es an sich also, wenn diese (irgendeine) Funktion für 0x30000 definiert ist. Die AVR-LIBC verschafft sich so z.B. auch Registerzugriff :-)
Sven P. wrote: > Es ist letztlich vollkommen wurscht, ob an '0x30000' irgendetwas > Brauchbares zu finden ist. <Nitpicking on> Bei C bin ich mir da nicht sicher, da kenn ich den Standard zuwenig. Aber bei C++ hast du auch diese Garantie nicht. Theoretisch gibt es laut Standard die Möglichkeit, dass die Zuweisung eines beliebigen Zahlenwertes an einen Pointer undefined behaviour (das Schreckgespenst im Standard) auslöst. Aus comp.lang.c-c++ weiß ich noch, das es wohl mal ein paar CPU gegeben hat, die für Adressen eigene Register hatten, und diese Register haben eine Exception ausgelöst, wenn ein ungültiger Wert in das Register geladen wurde (also kein Speicher an besagter Adresse lag). Wichtig: Allein schon das Laden des Wertes führte zur Exception, es musste noch nicht mal dereferenziert werden. Persönlich erlebt hab ich das auch noch nie, kenns nur vom Hörensagen. Allerdings sind die Leute in comp.lang.c-c++ in der Beziehung zuverlässig (einige von denen arbeiten beim Standard mit) <Nitpicking off>
K&R (zweite auflage, ANSI-C) sagt: > Ein Zeigerwert darf in einen Integer-Typ umgewandelt werden, der für ihn > groß genug ist; die nötige Größe ist implementierungsabhängig. Die > Abbildungsfunktion ist ebenfalls implementierungsabhängig. Es muss also nicht jede Ganzzahl unbedingt zu einem Zeiger korrespondieren, die Abbildungsfunktion könnte Lücken haben usw.
Hallo S. Meyer, eigentlich jede Implementierung muss eine Möglichkeit bieten, auf Speicherbereiche an bestimmten Adressen zugreifen zu können, weil da zum Beispiel I/O-Bereiche eingeblendet werden. Bei einem so wilden Typecast von int nach Zeiger garantiert einem aber niemand, dass es das tut, was man naiverweise erwartet. Besser wäre es wohl, eine entsprechende Variable mit fester Speicheradresse zu definieren, z.B. ein char-array, und die dann zu verwenden. Wie das genau geht verrät dir das Handbuch zu deinem Compiler. Gruß, DetlevT
> Besser wäre es wohl, eine entsprechende Variable mit fester > Speicheradresse zu definieren, z.B. ein char-array, und die dann zu > verwenden. Wie das genau geht verrät dir das Handbuch zu deinem > Compiler. Das hat auch den Vorteil, daß der Linker dann davon Kenntnis hat und nicht auf die Idee kommt, diesen Speicherbereich für was anderes zu benutzen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.