Und wieder Pointer-Verwirrung
-
normalerweise macht man das so:
int *p, wert = 666; p = &wert; cout << *p << endl;aber wieso geht es auch so:
*p = wert;dasselbe ergebnis? ist den beides überhaupt zuweisen?
und dennoch:
wenn ich *p++ mache kommt da irgendwelche komische zahlen raus 4198889
und wenn ich *p = wert; mache und dann *p++ dann kommt 0 raus.was passiert da eigentlich?
-
sorry, die komischen unicodes... die erste zeile nochmal
int *p, wert = 666;
-
Ich würde dir dringends empfehlen dich intensiver mit Pointern zu beschäftigen.
Fangen wir mal an:
int *p, wert =&666;Du definierst einen Zeiger namens "p" vom typ int,
und du definierst eine Variable vom typ int namens "wert", welche du mit 666 initialisierst.p = &wert;Du weist dem Zeiger p, die Adresse von der Variable "wert" zu.
Ab jetzt "zeigt" p auf die Stelle im Speicher, wo der Inhalt von 'wert' liegt.cout << *p << endl;du dereferenzierst den Zeiger p, und lässt ihn durch cout ausgeben.
Es wird das ausgegeben, was in der Speicherstelle steht, auf die p zeigt (also das, was in "wert" steht).Nun zu deiner Verwirrung:
aber wieso geht es auch so:
*p = wert;int *p, wert = 666; *p = wert; cout << *p << endl;Puuuh... hoffentlich geht das NICHT. Was du machst ist nicht empfehlenswert.
Du benutzt einen nicht initialisierten Zeiger (manche sagen auch wild pointer).
Keiner weiss wirklich auf welche Speicherstelle er zeigt, und wenn du nun in dem Speicher rumschreibst (mit "*p = wert;" zB), weiss keiner was du gerade überschreibst. Im günstigsten Fall stürzt das Programm ab und dein Betriebssystem gibt dir eine schöne Fehlermeldung (Segfault, Ausnahmefehler blabla). Im ungünstigsten Fall löst Du damit den dritten Weltkrieg aus.Ein gültiges Beispiel damit wäre folgendes:
int *p, wert = 666; p = &wert; *p = wert; cout << *p << endl;Hierbei wird mit "*p = wert;", der Zeiger p dereferenziert, und an die Speicherstelle auf die er zeigt, den Inhalt aus "wert" geschrieben. Was im Grunde genommen doppelt gemoppelt ist. Er holt sich die 666 von "wert" und legt sie dort ab, wo die 666 schon steht.
Noch mehr Verwirrung:
wenn ich *p++ mache kommt da irgendwelche komische zahlen raus 4198889
Willkommen in der wundervollen Welt des Operatorenvorrangs.
Heute kämpfen der Derefenzierungsoperator gegen den Postinkrement.
Let's get ready to rumbleeeeeeeeee.... *langzieh*
Oh, und direkt der Knockout in der ersten Runde!
And the winner is: POSTINKREMENT.Okay, spass beiseite.
Du musst aufpassen, was wann passiert.
Der Postinkrement wird VOR dem Deref-Operator ausgewertet.
In p steht nun eine Speicheradresse. Diese inkrementierst du (und zwar um die Größe vom Zeigertyp - also in deinem Fall int. - macht locker 2 - 4 bytes). Dann schaust du erst was in dieser Speicherzelle abgelegt ist.
Hat dich natürlich brennend interessiert, was hinter deiner 666 noch so alles steht, nicht wahr? Nicht? Oh, dann habe ich noch was:
Für diesen Fall hat Gott (nagut, vielleicht war es auch Kernighan oder Ritchie) die sogenannten Klammern erfunden. Sind endlos praktisch wenn man zu faul ist Operatorenvorrang zu lernen
Was du gerne machen möchtest ist:(*p)++;Dann wird aus deiner 666, fluchs eine 667.
Noch Fragen?

-
ja ok vielen vielen dank für die Mühe! ich hoffe ich verstehe es. ist halt nur merkwürdig wenn ich ++*p mache dann kommt auch 667 raus. Wenn dagegen *p++ dann merkwürdige Zahlen. Jedenfalls experimentiere ich sehr viel, und wenn ich feststelle es geht irgendwie auch so und so und im Buch steht nix dann will man es untersuchen wieso

-
also kann es sein dass die pointers manchmal gefährlich sind? Also wie eine Schusswaffe? wenn noch andere Programme offen sind und ebenfalls Speicher belegen. Könnte ich mit meinen Programm auf fremde Speicherbereiche zugreifen und verändern. Quasi andere Software zerschiessen? Und manchmal zerstört es nicht, sondern verändere nur die Werte und das fremde Programm verhält sich komisch? Wie radioaktive Strahlen die nicht immer zerstören sondern auch verändern?
-
nein, auf andere Prozesse kannst du so nicht zugreifen. du musst wissen, dass auf einem win32-rechner jedes Programm virtuell 4GB ram zugesichert bekommt. Das ist dein speicher, auf dem kannst du schreiben. Du kommst aber mit einem normalen pointer nicht auf den (virtuellen) speicher eines anderen Prozesses.
Unter windows gibt es dazu readprocessmemory und writeprocessmemory
-
hm wundert mich grad, wie hackersoftware und andere cheats andere programme zur laufzeit verändern können - letzte frage noch:
kann man pointers auf normale zahlen zuweisen?
also wenn irgendwo im quellcode eine 4 steht, die ja eigentilch Konstante ist, kann man mit Pointers da drauf zuweisen? Oder geht das nur bei Variablen?
weil ich hab nämlich so gemacht:
*p = 3; (*p)++;Ein mal ist es abstürzt. dann hab ich andere zeilen die damit nix zu tun haben auskommentiert. dann gehts. In der Ausgabe kommt 4 raus. Sollte eigentlich dasselbe wie bei Werten nicht empfehlenswert sein, nehme ich an.
und hier: so kommt Compilierfehler raus ^^
p = &3so auch nicht:
p = &(3)als konstante Zeiger auch nicht

-
hmm
int* pInt = new int; *pInt = 3; delete pInt;
-
x:
Die Gefahr von Pointern relativiert sich größtenteils bei Software für Personal Computer. Prinzipiell könntest du einen Pointer auch auf Speicher zeigen lassen, der einem Anderen Prozess oder gar dem Kernel gehört.
Jedoch liegt zwischen deinem Programm und dem Speicher noch dein Betriebssystem, was es höchstwahrscheinlich zu verhindern weiss und dein Programm abstürzen lässt (als mildeste Konsequenz sozusagen
).
Trotzdem ist es mit Mitteln die dein Betriebssystem liefern (win32-api zB) möglich, den Speicher von fremden Prozessen zu manipulieren (Stichwort Game-Trainer zB).----
Pointern kannst du _nicht_ die Adresse von Konstanten zuweisen.
Zum einen ist nicht definiert wie der Compiler Konstanten schlussendlich in Maschinencode umsetzt, zum anderen ist nicht ersichtlich ob die Konstante in einem Speichersegment liegt, in dem du überhaupt mit deiner Pointerei arbeiten darfst