Entwickler-Ecke
Off Topic - C++: void* zur Adressfindung?
Jakob_Ullmann - Sa 12.06.10 13:52
Titel: C++: void* zur Adressfindung?
Hi!
Bei Wikibooks (
http://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Weitere_Grundelemente/_Zeiger ) findet man folgendes:
| Zitat: |
void-Zeiger (anonyme Zeiger)
Eine besondere Rolle spielen die „Zeiger auf void“, die so genannten generischen Zeiger. Einem Zeiger vom Typ void* kann jeder beliebige Zeiger zugewiesen werden. void-Zeiger werden in der Sprache C z.B. bei der dynamischen Speicherverwaltung verwendet. In C++ kommt man weitgehend ohne sie aus. Vermeiden Sie Zeiger auf void wenn Sie eine andere Möglichkeit haben.
Eine Variable kann nicht vom Typ void sein. Daher würde folgende Zeile zu einem Fehler führen:
Sie können einer Variable, die auf void zeigt, einen beliebigen Zeiger zuweisen. Deshalb werden solche Variablen meist für Zeiger verwendet, dessen Typ noch nicht feststeht und sich erst im Laufe des Programmes ergibt oder aber als temporärer Speicher mit wechselnden Zeigertypen.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| #include <iostream>
int main() { int intValue = 1; int *intPointer = &intValue; void *voidPointer; voidPointer = intPointer; … |
Sie können jetzt nicht ohne Weiteres auf *voidPointer zugreifen, um an die Adresse von intValue zu bekommen. Da es sich um einen Zeiger, vom Typ void handelt, muss man diesen erst casten. In diesem Fall nach int*.
C#-Quelltext 1: 2: 3:
| … std::cout << *reinterpret_cast<int*>(voidPointer) << std::endl; } |
Ablauf im Detail:
1. Zeiger *voidPointer ist vom Typ void und zeigt auf intValue
2. reinterpret_cast<int*>, Zeiger ist vom Typ int*
3. Zeiger dereferenzieren ( *), um Wert zu erhalten
|
Ich verstehe irgendwie nicht ganz, warum das klappen soll. Das fängt hier an:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| int main() { int intValue = 1; int *intPointer = &intValue; void *voidPointer; voidPointer = intPointer; |
voidPointer zeigt auf intPointer? Müsste voidPointer nicht eher auf intValue zeigen? Hier wird doch der Zeiger und nicht seine Referenz übernommen, oder hat void* da eigene Syntaxregeln? Logischer wäre für mich dann eher das hier:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| void *voidPointer = intPointer;
bzw.
void *voidPointer; voidPointer = &intPointer; |
Vll. ein Tippfehler bei Wikibooks? Aber warum kann ich das dann nicht einfach so machen:
C#-Quelltext
1: 2: 3: 4:
| int iValue = 1; int *pValue = &iValue;
int addr = reinterpret_cast<int> (pValue); |
Warum geht der eine Cast, aber der andere nicht?
Bergmann89 - Sa 12.06.10 15:30
Hey,
also das mit dem Zeiger auf intPointer is wirklich Mist! Das is ein und der selbe Zeiger, bloß das der eine eben vom Typ int is un der andere void is. Das mit der Ausgabe stimmt so. Erst sagst du das der voidPointer ein intPointer ist (mit (int*)) und dann holst du dir den Wert auf den der Pointer zeigt (mit * vor dem ganzen). Und die Zahl wird dann ausgegeben. Wenn du nur den voidPointer wieder in ein intPointer casten willst müsste das so aussehen:
int *intPointer = (int*)voidPointer;
Bei deinem Beispiel castest du den Pointer in ein int, heißt du zeigst die Adresse, auf die der Pointer zeigt als ein Integer an und nicht den Wert an der Adresse.
€: hier ma noch ein Bsp.:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| int main(int argc, char *argv[]){ int intValue = 1; int *intPointer = &intValue;
void *voidPointer; voidPointer = intPointer;
int* intPointer2 = (int*)voidPointer; cout << *intPointer2; cout << *(int*)voidPointer; cin.get();
return 0; } |
MfG Bergmann.
Jakob_Ullmann - Sa 12.06.10 16:45
Danke!
Bergmann89 hat folgendes geschrieben : |
Bei deinem Beispiel castest du den Pointer in ein int, heißt du zeigst die Adresse, auf die der Pointer zeigt als ein Integer an und nicht den Wert an der Adresse. |
Darum ging es mir ja auch. Aber so wie ich das verstanden hatte, war das ja auch das Ziel bei Wikibooks, aber der Abschnitt war wirklich sehr konfus geschrieben. Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss. Wobei: Delphi lässt ja auch nicht DWORD(Pointer) zu (aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ).
Kha - Sa 12.06.10 17:08
Jakob_Ullmann hat folgendes geschrieben : |
| Aber so wie ich das verstanden hatte, war das ja auch das Ziel bei Wikibooks |
Denke ich nicht, es soll sicherlich
| Zitat: |
| Sie können jetzt nicht ohne Weiteres auf *voidPointer zugreifen, um an die Adresseden Wert von intValue zu bekommen. |
heißen. Dann passen Wort und Tat auch wieder zusammen ;) .
Jakob_Ullmann hat folgendes geschrieben : |
| Wobei: Delphi lässt ja auch nicht DWORD(Pointer) zu |
Seit wann das denn nicht mehr :gruebel: ?
Jakob_Ullmann hat folgendes geschrieben : |
| (aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ). |
Dürfte in C auch nicht ganz einfach werden, so ganz ohne Byte-Typ ;) .
Greenberet - Sa 12.06.10 17:29
Jakob_Ullmann hat folgendes geschrieben : |
| Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss. |
muss man doch nicht?
'&' holt die Adresse von intValue und diese weist du halt in dem Beispiel dem Pointer zu. du könntest dir das natürlich sparen und gleich direkt mit &intValue arbeiten.
Jakob_Ullmann hat folgendes geschrieben: |
Jakob_Ullmann hat folgendes geschrieben : | | (aber in Delphi kann ich ja nicht mal einem Char ein Byte zuweisen. :P ). | Dürfte in C auch nicht ganz einfach werden, so ganz ohne Byte-Typ ;) . |
dann mach dir doch einfach einen :P
typedef unsigned char byte; voila ein Byte Datentyp wurde geboren ;)
Bergmann89 - Sa 12.06.10 18:59
Hey,
Jakob_Ullmann hat folgendes geschrieben : |
| Mir kam es nur halt komisch vor, dass man zum Holen der Adresse erst einen Umweg über void machen muss. |
Das kapitel heißt ja bestimmt nich "Pointer - Adresszuweisung" sondern "Einführung void-Pointer" das is bloß n dummes Bsp, welches an der Stelle überhaupt kein Sinn hat ;)
MfG Bergmann
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!