www.mikrocontroller.net

Forum: PC-Programmierung C++, Pointer, direkte Adresse verwenden?


Autor: abc xyz (enybase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Musst das Literal 0x30000 casten, da es ein int oder ein long ist:
Irgendwie so:
int* ptr = (int *)0x30000;

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Kunz wrote:

> Wenn es innerhalb eines Betriebssystemes läuft wird diese Zuweisung
> zu einem Fehler führen.

Nein.

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
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 :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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>

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.