Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Pointer : Eine Speicherstelle weiterrücken (https://www.delphipraxis.net/18010-pointer-eine-speicherstelle-weiterruecken.html)

braingrenade 12. Mär 2004 19:19


Pointer : Eine Speicherstelle weiterrücken
 
Moin Leute !


Hab ein Problem mit den allseits beliebten Pointern :

Wie kann ich einen die in einem Pointer P gespeicherte adresse
um eine Speicherstelle weiterbewegen?

In der OH steht dazu :

Code:
If I is an integer and P is a character pointer, then P + I adds I to the address given by P; that is, it returns a pointer to the address I characters after P. (The expression I + P is equivalent to P + I.) P ? I subtracts I from the address given by P; that is, it returns a pointer to the address I characters before P.
Nun hab ich folgenden Code :

Delphi-Quellcode:
var Pinput : Pointer;
begin
pinput := Pinput + 1;
Geht aber nicht : [Error] INN.pas(73): Operator not applicable to this operand type

ich habs auch noch so probiert :

Delphi-Quellcode:
 pinput := byte(Pinput) + 1;
was aber auch nicht zum gewünschten Ergebniss führt : [Error] INN.pas(73): Incompatible types: 'Integer' and 'Pointer'

Weiß jemand wie ich das Lösen könnte ?

Luckie 12. Mär 2004 19:44

Re: Pointer : Eine Speicherstelle weiterrücken
 
Versuch es mal mit Inc. Als zweiten Parameter kannst die Schrittweite angeben, also sizeof(Integer).

braingrenade 12. Mär 2004 19:50

Re: Pointer : Eine Speicherstelle weiterrücken
 
hmmm ...

funtioniert leider auch nicht :

Delphi-Quellcode:
 inc(pinput,sizeof(byte)); //[Error] INN.pas(74): Ordinal type required

 inc(pinput); //[Error] INN.pas(74): Ordinal type required

braingrenade 12. Mär 2004 19:57

Re: Pointer : Eine Speicherstelle weiterrücken
 
Problem gelöst !! :cheers:

Delphi-Quellcode:
var pinput : pointer;
    P : Pbyte;
begin
    P := pinput;
    inc(P);
end;
Dankescheeen !

atreju2oo0 12. Mär 2004 20:09

Re: Pointer : Eine Speicherstelle weiterrücken
 
Also das was Du brauchst ist eine Liste

Code:
type
      PListe : ^TListe;
      TListe = record
      wert : integer // beliebige Variablen;
      next : PListe; // zeigt auf das nächste Element

var Anker,help:PListe; // Anker speichert das ERSTE Element und wird NIE verändert; help durchläuft die Liste
Im OnCreate musst Du nun noch die Zeiger initialisieren
Code:

new(Anker);// Reserviert Speicher für die Variable
An irgendeiner Stelle musst Du die Werte einlesen; Das geht so:
Code:
 help:=anker; // Setzt die Hilfsvariable auf die Erste Stelle

repeat
 new(help.next); // Erzeugt eine neue Variable und speichert den Zeiger dieser Variable in help.next ab
 help:=help.next; // Jetzt rutscht man mit help in der Liste eins hoch
 help.wert:=2    // Hier kannst Du Daten ändern
 Help.next:=nil; // und setzt den neuen Nachfolger, der ja noch nicht erzeugt wurde auf 0 
until fertig...
und mit der Struktur kannst Du dann ganz locker eins hoch rutschen indem du
Code:
 help:=help.next
benutzt...

Am Ende des Programms musst Du den Speicher noch freigeben
indem Du diese Procedure mit clearanker(Anker) aufrufst
Code:
  procedure clearanker(help: PListe);
    begin
      if help.next<>nil then clearanker(help.next);
      dispose(help);
    end;
Ich hoffe das löst dein Problem...

atreju2oo0 12. Mär 2004 20:11

Re: Pointer : Eine Speicherstelle weiterrücken
 
oder so... :wall:

braingrenade 12. Mär 2004 20:20

Re: Pointer : Eine Speicherstelle weiterrücken
 
Nee , Listen mag ich net so , aber troztdem danke für die Mühe !

Sebastian Nintemann 12. Mär 2004 20:22

Re: Pointer : Eine Speicherstelle weiterrücken
 
Liegt, wenn ich mich nicht irre, daran, dass der Pointer typisiert sein muss. Es wird immer um soviel byte weitergerückt, wie eine Speichereinheit des referenzierten Typs belegt. Inc(p) bewirkt also zB das "vorrücken" um vier byte falls p ein PInteger ist.

Gruß, Sebastian

Christian Seehase 12. Mär 2004 20:35

Re: Pointer : Eine Speicherstelle weiterrücken
 
Moin Braingrenade,

es ginge auch

Delphi-Quellcode:
inc(PByte(pinput));

braingrenade 12. Mär 2004 20:41

Re: Pointer : Eine Speicherstelle weiterrücken
 
Ahh , das ja noch praktischer !

atreju2oo0 13. Mär 2004 08:19

Re: Pointer : Eine Speicherstelle weiterrücken
 
Source:
inc(PByte(pinput));

Dann ist also festgelegt, dass der Compiler jeden Pointer hintereinander speichert?
Was ist wenn zum Beispiel Pointer1 an einer anderen Stelle gespeichert wird als Pointer2?
Dann geht der inc Algorithmus doch nicht mehr, oder?
Wäre nett wenn mich mal jemand aufklärt... Ist ja doch nen bissle kürzer als meine Variante... :gruebel:

SirThornberry 13. Mär 2004 09:33

Re: Pointer : Eine Speicherstelle weiterrücken
 
sollte auch so gehen
Delphi-Quellcode:
Integer(pInput) := Integer(Pinput) + 1;

Christian Seehase 13. Mär 2004 10:52

Re: Pointer : Eine Speicherstelle weiterrücken
 
Moin atreju,

es wird nicht jeder Pointer hintereinander gespeichert, sondern es geht darum wie man an Daten herankommt, die im Speicher unmittelbar hintereinander liegen.
Dann benötigt man nur die Adresse des ersten Byte, und kann dann, durch ein einfaches Inc auf das nächste Element kommen.
Da die Variable pinput ein untypisierter Pointer ist, "weiss" der Compiler nicht, wie der den Inc Befehl umsetzen soll, da die Compiler Magic auf Grund des Typs des Pointers weiss, um wieviel der Wert erhöht werden muss.
In dem Beispiel handelt es sich um eine Pointer auf einzelne Bytes, und der Typecast mit PByte(...) dient nur dazu dem Compiler mitzuteilen, dass er den Wert der Variablen um 1 hochzählen soll.
Hätte man geschrieben

Delphi-Quellcode:
inc(PDWORD(pinput));
würde pinput um 4 erhöht werden, da ein DWORD eben 4 Byte belegt.

Das funktioniert dann genauso mit Pointern auf beliebige Datenstrukturen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz