Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Pointer auf record
peeage - Mi 05.05.10 19:29
Titel: Pointer auf record
Hallo zusammen,
wenn ich einen Pointer auf ein record erhalte, zeigt dieser dann auf das erste Feld in diesem record, so dass ich rein theoretisch mit dem incrementieren des Pointers zu den nachfolgenden Feldern gelange?
JayEff - Mi 05.05.10 19:45
Wie meinst du das? Wie dereferenzierst du den Pointer?
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| rec.feld1 := 1; rec.feld2 := 2; rec.feld3 := 'asd'; prec := @rec;
prec^.feld1 := 1; |
Tryer - Mi 05.05.10 19:49
Ja, der Pointer zeigt auf den Speicherplatz des ersten Elements.
Beim Inkrementieren it der Typ des Pointers ist wichtig, ein PByte würde auf das nächste Byte, ein PInteger 4 Byte weiter zeigen.
JayEff - Mi 05.05.10 20:06
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| type my_rec = record feld1, feld2: Integer; feld3: String; feld4: Integer; end;
var rec: my_rec; prec: PInteger; begin rec.feld1 := 1; rec.feld2 := 2; rec.feld3 := 'asrdrdd'; rec.feld4 := 3; prec := @rec;
showmessage(IntToStr(prec^)); inc(prec); showmessage(IntToStr(prec^)); inc(prec); showmessage(IntToStr(prec^)); inc(prec); showmessage(IntToStr(prec^)); |
Hierbei bekommt man relativ sinnloses im dritten Aufruf aber der vierte klappt wieder einwandfrei und gibt die 3 aus.
Martok - Mi 05.05.10 20:16
JayEff hat folgendes geschrieben : |
Hierbei bekommt man relativ sinnloses im dritten Aufruf |
Nämlich - der Vollständigkeit halber - den Zeiger auf die String-Daten. String ist nämlich erstmal nur ein Zeiger auf ein Stück mit Compiler-Magic verwalteten Speicher.
JayEff - Mi 05.05.10 21:30
Richtig. Wie sieht es mit typen aus, die kein Zeiger sind und mehr Bytes belegen als ein Integer? Vermutlich bekommst du dann einen als Integer interpretierten Abschnitt des typen. Also würde ich abschließend behaupten: Tu's nur, wenn du genau weißt, was du tust: Wenn der record aus gleichgroßen Feldern besteht, kannst du das z.B. so machen.
Tryer - Mi 05.05.10 21:36
Die Dereferenzierung eines PInteger (PInteger^) liefert halt immer etwas zurück das als Integer interpretiert wird - solange PInteger auf eine Stelle verweist wo dir erlaubt ist 4 Byte auszulesen (sonst gibt es ggf. eine Zugriffsverletzung).
Genauso wie du eine Speicherstelle als Integer interpretieren kannst, so kannst du sie auch (hier via Casting) als String interpretieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| showmessage(IntToStr(prec^)); inc(prec); showmessage(IntToStr(prec^)); inc(prec); showmessage(string(prec^)); inc(prec); showmessage(IntToStr(prec^)); |
Wie JayEff schon sagte, das sollte man nur machen wenn man sich der Sache sicher ist welche Daten an der Stelle stehen.
dummzeuch - Mi 05.05.10 21:44
peeage hat folgendes geschrieben : |
wenn ich einen Pointer auf ein record erhalte, zeigt dieser dann auf das erste Feld in diesem record, so dass ich rein theoretisch mit dem incrementieren des Pointers zu den nachfolgenden Feldern gelange? |
Das kommt auf den Typ des Pointers an. Ein PByte wird immer um 1 incrementiert, ein PInteger immer um 4, d.h. er wird immer um die Groesse des Typs incrementiert, auf den er laut Deklaration zeigt. Deshalb kann man auch mit einen Pointer auf den in einem Array gespeicherten Record alle Records im Array durchgehen.
Schwierig wird es, wenn der Record Felder mit unterschiedlichen Datentypen hat, denn dann kann der Pointer beim Incrementieren auf ungueltige Daten zeigen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| type TMyRec = record eins: integer; zwei: byte; drei: word; end; var MyRec: TMyRec; ThePointer: PInteger; begin MyRec.eins := 1; MyRec.zwei := 2; MyRec.drei := 3; ThePointer := @MyRec; WriteLn(ThePointer^); Inc(ThePointer); WriteLn(ThePointer^); |
Narses - Do 06.05.10 00:24
Moin!
Der Vollständigkeit halber werfe ich nochmal das Schlüsselwort packed ind den Raum, Details - zu diesem insgesamt definitiv nicht empfehlenswerten Vorgehen - in der DOH. :idea:
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 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!