Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Pointeradresse auslesen (https://www.delphipraxis.net/201931-pointeradresse-auslesen.html)

paul.kunig 11. Sep 2019 09:38

Delphi-Version: 5

Pointeradresse auslesen
 
Hallo zusammen,

folgender Code:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Eingabe: ^String;
begin
  New(Eingabe);
  Eingabe^ := Edit1.Text;

  ShowMessage(Eingabe^ + #13#10 +
  IntToStr(Integer(Eingabe)) + #13#10 +
  IntToStr(Integer(@Eingabe)) + #13#10 +
  IntToStr(Integer(Addr(Eingabe)))
  );

  Dispose(Eingabe);
end;
Führe ich das Ganze aus, erhalte ich folgende Werte:
1) Inhalt des Eingabefeldes
2) Einen Dezimalwert, der auch unter lokale Variablen in der Entwicklungsumgebung als Hexadezimalwert angezeigt wird.
3) Einen siebenstelligen Integer
4) Den selben Integer wie in Punkt 3.

Welcher von diesen Werten ist nun die Speicheradresse des Zeigers und woher kommt der verbliebene Wert?

Gruß
Paul

Amateurprofi 11. Sep 2019 10:44

AW: Pointeradresse auslesen
 
Siehe eingefügte Kommentare im Code
Delphi-Quellcode:
var
   Eingabe: ^String;
begin
   New(Eingabe);
   Eingabe^ := Edit1.Text;

   ShowMessage(Eingabe^ + #13#10 +          // Der Text aus dem Edit nach Eingabe kopierte Text
   IntToStr(Integer(Eingabe)) + #13#10 +    // Adresse des mit New allozierten Speicherbereichs
   IntToStr(Integer(@Eingabe)) + #13#10 +   // Adresse der Variablen "Eingabe"
   IntToStr(Integer(Addr(Eingabe)))        // dto
   );

   Dispose(Eingabe);
end;

paul.kunig 11. Sep 2019 11:00

AW: Pointeradresse auslesen
 
Hallo Amateurprofi,

danke für deine Antwort. Noch einmal zum Verständnis.

Die Variable "Eingabe" ist eine Typisierter Zeiger.
In diesen Speicherbereich wird der Wert aus dem Eingabefeld gespeichert.

Also sollte ich zwei Werte abrufen können.
1) Den Werte der unter dieser Speicheradresse abgelegt ist.
2) Die Adresse wo der Wert abgelegt ist.

Aus welchem Grund sollte die Variable "Eingabe", die ja ein Zeiger ist, erneut eine Speicheradresse bekommen?

Gruß
Paul

Amateurprofi 11. Sep 2019 11:24

AW: Pointeradresse auslesen
 
Zitat:

Zitat von paul.kunig (Beitrag 1445695)
Hallo Amateurprofi,
Also sollte ich zwei Werte abrufen können.
1) Den Werte der unter dieser Speicheradresse abgelegt ist.
2) Die Adresse wo der Wert abgelegt ist.
Aus welchem Grund sollte die Variable "Eingabe", die ja ein Zeiger ist, erneut eine Speicheradresse bekommen?

Gruß
Paul

Zu 1) und 2):
Kannst und machst Du doch
1) Den Werte der unter dieser Speicheradresse abgelegt ist.
Delphi-Quellcode:
Eingabe^
.
2) Die Adresse wo der Wert abgelegt ist.
Delphi-Quellcode:
Eingabe
.
3) Aus welchem Grund sollte die Variable "Eingabe", die ja ein Zeiger ist, erneut eine Speicheradresse bekommen?
Weil Du mit
Delphi-Quellcode:
New(Eingabe)
diesen Speicherbereich allozierst und die Adresse dieses Speicherbereichs in Eingabe stellst.

Das New und Dispose kannst Du auch weglassen, indem Du Eingabe als String deklarierst also:
Delphi-Quellcode:
var Eingabe:String;
und
Delphi-Quellcode:
Eingabe:=Edit1.Text;

paul.kunig 11. Sep 2019 12:54

AW: Pointeradresse auslesen
 
Ich möchte den Wert des Eingabefeldes im Heap speichern, daher der Typisierte Zeiger.

Um den Wert aus dem Speicherbereich auszulesen wird dieser dereferenziert, also Eingabe^.
Um die Speicheradresse auszulesen wird @ oder Addr() verwendet.

So weit, so gut.

Wenn ich den Zeiger nicht mit New() erzeuge, gibt es eine Zugriffsverletzung.
Also ist diese Speicherzuweisung notwendig.

Wozu sollte noch eine Adresse für ein und die selbe Variable, in diesem Fall ein Zeiger, benötigt werden.

Wobei diese anscheinend in verschiedenen Bereichen des Speichers abgelegt sind.
Adresse des Zeigers = achtstellig.
Adresse der Variable, die ja der Zeiger ist = siebenstellig.

Es erschließt sich mir nicht, warum die Adresse eines Zeigers in einer Variable gespeichert werden soll, obwohl der Zeiger selber die Möglichkeit bietet sich selber auszulesen.

Was übersehe ich?

Amateurprofi 11. Sep 2019 13:51

AW: Pointeradresse auslesen
 
Zunächst mal:
Wir sprechen über Delpi 5, wenn ich #1 richtig interpretiere, also String = ShortString.

Zitat:

Ich möchte den Wert des Eingabefeldes im Heap speichern, daher der Typisierte Zeiger.
.
Was aber aus #1 nicht hervorgeht.

Zitat:

Wenn ich den Zeiger nicht mit New() erzeuge, gibt es eine Zugriffsverletzung.
Also ist diese Speicherzuweisung notwendig.
.
Ja, wenn "Eingabe" als ^String deklariert ist, ist das so.

Zitat:

Wozu sollte noch eine Adresse für ein und die selbe Variable, in diesem Fall ein Zeiger, benötigt werden.
.
"Eingabe" ist die Variable, in der die Adresse des allozierten Speicherbereiches steht.
Der Inhalt von "Eingabe" ist diese Adresse.
Also: Die Variable "Eingabe" und die Adresse des allozierten Speicherbereiches sind nicht dasselbe.
Egal, ob du den Speicher mit New(Eingabe) oder z.B. mit GetMem(Eingabe, SizeOf(String)) allozierst, brauchst du einen Ort, wo die Adresse des allozierten Speichers gespeichert wird

Zitat:

Wobei diese anscheinend in verschiedenen Bereichen des Speichers abgelegt sind.
Adresse des Zeigers = achtstellig.
Adresse der Variable, die ja der Zeiger ist = siebenstellig.
.
"Eingabe" ist eine lokale Variable, die auf dem Stack angelegt wird.
Der mit New allozierte Speicher liegt dagegen auf dem Heap.
Der Stack wächst von oben nach unten, der Heap aber von unten nach oben.
Heap und Stack sind also unterschiedliche Speicherbereiche.

Zitat:

Es erschließt sich mir nicht, warum die Adresse eines Zeigers in einer Variable gespeichert werden soll, obwohl der Zeiger selber die Möglichkeit bietet sich selber auszulesen.
.
Wie stellst Du Dir denn vor zunächst einen Speicherbereich für den Text zu allozieren und anschließend den Text in diesem zu speichern, wenn Du die Adresse des Speicherbereiches nicht irgendwo speicherst?

Sherlock 11. Sep 2019 14:09

AW: Pointeradresse auslesen
 
Ich hoffe doch sehr, die Diskussion ist akademischer Natur. Pointer und Hantiererei mit ihnen (dazu gehört auch die drollige Pointerarithmetik) ist in einer guten Objektorientierten Sprache (ja, auch Delphi gehört dazu) weggekapselt. Durch falschen Behandlung von Pointern (von Speicherverwaltung über Fehladressierungen zu Pufferüberläufen) geht viel zu viel schief, das vermeidbar wäre. Pointer braucht man heutzutage nur noch in extremen Ausnahmefällen wie Aufrufe ungekapselter OS-Methoden oder auch Treibergeschichten.

Sherlock

paul.kunig 11. Sep 2019 15:23

AW: Pointeradresse auslesen
 
Hallo Klaus,

wieso Delphi 5? Wurde nicht von mir eingetragen.

In der Signatur steht doch Delphi 10 Seattle!

Zitat:

Was aber aus #1 nicht hervorgeht.
Ich habe im ersten Thread die komplette Routine hineingeschrieben.
Daraus geht eindeutig hervor, dass es sich um einen Typisierten Zeiger handelt, der meiner Meinung nach im Heap gespeichert wird.

Zitat:

Ja, wenn "Eingabe" als ^String deklariert ist, ist das so.
Ja, ist im ersten Thread klar erkennbar.
Bitte Beitrag richtig lesen, um weitere Verwirrung meinerseits zu vermeiden.

Zudem schreibst du in deiner ersten Antwort, dass
Delphi-Quellcode:
IntToStr(Integer(Eingabe)) + #13#10 + // Adresse des mit New allozierten Speicherbereichs
,

wobei die beiden anderen Aufrufe(@ und Addr()) für Adresswiedergabe zuständig sind.

Also noch einmal:
Wenn "Eingabe" ein Typisierter Zeiger ist, sollte folgendes gelten/funktionieren.

Eingabe^ = Ausgabe des Speicherinhaltes/abgelegten Wertes
IntToStr(Integer(@Eingabe)) = Ausgabe der Speicheradresse
IntToStr(Integer(Addr(Eingabe))) = Ausgabe der Speicheradresse
IntToStr(Integer(Eingabe)) = ? (ohne Dereferenzierung)

Hierbei ist noch folgendes zu erwähnen.
Der zurückgegebene Wert aus IntToStr(Integer(Eingabe)) entspricht genau dem Wert, der in Überwachte Ausdrücke/Lokale Variablen im Feld Wert angezeigt wird, lediglich von Hexadezimal zu Integer umgewandelt.

Was gibt IntToStr(Integer(Eingabe)) zurück, wenn, wie in diesem Fall, Eingabe ein Zeiger ist?

Gruß

freimatz 11. Sep 2019 16:40

AW: Pointeradresse auslesen
 
Mit "New(Eingabe)" machst Du einen pointer auf dem Heap. ok.
Du weist Eingabe jedoch nichts zu, in dem Fall ist das IMHO dann undefniert. Eingabe zeigt also irgendwohin.
Mit "Eingabe^ := Edit1.Text;" behandelst du dann das irgendwo als einen String und schreibst da etwas rein.

Wenn Du wirklich die Speicheradresse des Zeigers haben willst, dann wäre das bei dir 3. und 4.
Es nutzt dir aber rein gar nichts wenn du "den Wert des Eingabefeldes im Heap speichern" willst.

paul.kunig 11. Sep 2019 16:54

AW: Pointeradresse auslesen
 
Wieso weise ich nichts zu?
Der Inhalt(Wert) des Eingabefeldes wird unter der Speicheradresse des Zeigers abgelegt.

@ und Addr() sind laut Delphi für die Ausgabe der Speicheradresse vorgesehen, richtig.

Aber was gibt IntToStr(Integer(Eingabe)) zurück, wenn, wie in diesem Fall, Eingabe ein Zeiger ist?
Ist die Frage so schwer, drücke ich mich falsch aus oder kann ich mein Anliegen nicht klar darstellen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 Uhr.
Seite 1 von 3  1 23      

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