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 Speicherinhalt geht verloren (https://www.delphipraxis.net/216287-pointer-speicherinhalt-geht-verloren.html)

Matthias. 4. Dez 2024 12:22

Delphi-Version: 12 Athens

Pointer Speicherinhalt geht verloren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich habe eine Frage zu Pointern in Delphi.
Delphi-Quellcode:
type

  PMyList = ^TStringList;
  TMyList = TStringList;

  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Test;
  private
    FMyList: TMyList;
    FMyListPointer: PMyList;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  LTempList: TMyList;
begin
  LTempList := TMyList.Create;

  LTempList.Add('Test1');
  LTempList.Add('Test2');
  LTempList.Add('Test3');
  FMyList := LTempList;
  FMyListPointer := @LTempList;

  Test;
end;

procedure TForm1.Test;
var
  LMyList: TMyList;
  LMyListFromPointer: TMyList;
  LAddr1: Pointer;
  LAddr2: Pointer;
  LTemp: String;
begin
  LAddr1 := @FMyList;
  LAddr2 := @FMyListPointer;

  LMyList := FMyList;
  LMyListFromPointer := FMyListPointer^;
  LTemp := LMyList[0];
  LTemp := LMyListFromPointer[0];
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  LMyList: TMyList;
  LMyListFromPointer: TMyList;
  LAddr1: Pointer;
  LAddr2: Pointer;
  LTemp: String;
begin
  LAddr1 := @FMyList;
  LAddr2 := @FMyListPointer;

  LMyList := FMyList;
  LMyListFromPointer := FMyListPointer^;
  LTemp := LMyList[0];
  LTemp := LMyListFromPointer[0];
end;

end.
Setze ich nun einen Haltepunk in der procedure Test bekomme ich folgendes Ergebnis:
LAddr1 und LAddr2 ist fast gleich aber leider nicht komplett gleich. Jedoch müsste die Adresse von beiden doch gleich sein ?
Bsp.
LAddr1 = $38B142C
LAddr2 = $38B1430
In den beiden lokalen Listen stehen die gleichen Werte LTempList in FormCreate. Das würde auch passen.

Die Procedure Timer1Timer kommt nach einer Sekunde.
Die beiden Adressen sind gleich wie in der Test Procedure.
In der LMyList stehen die Werte meiner List.
Das Problem ist, dass die Liste LMyFromPointer leer ist.

Mache ich irgendetwas falsch oder gibt es hierzu bekannte Probleme ?


Ich hoffe ich konnte mein Problem verständlich erleutern und im Voraus bereits vielen Dank für eure Unterstützung.

GueAck 4. Dez 2024 23:00

AW: Pointer Speicherinhalt geht verloren
 
Hallo,

Du hast mit FMyList und MyListPointer zwei Variablen angelegt. Mit @ zeigst Du die Speicheradressen dieser Variablen an. Die Definitionen der Variablen erfolgen unmittel aufeinander, deshalb ergibt das genau 4 Byte Differenz in DeinerAnzeige im Debugger. Vertausch die Deklarationen mal, dann werden auch die Inhalte ausgetauscht sein.

Im Debugger sollte FMyList auf eine Adresse irgendwo im Speicher zeigen, eben da wo der Compiler die Listenstruktur angelegt hat,

Probiere mal und melde Dich wieder.

Gruß
GueAck

himitsu 4. Dez 2024 23:40

AW: Pointer Speicherinhalt geht verloren
 
@LTempList zeigt auf die lokale Variable der Prozedur FormCreate.
Natürlich gibt diese Prozedur am Ende ihre Variablen frei und der Zeiger zeigt nicht mehr auf das, was du denkst.
Im Timer1Timer ist somit diese Variable garantiert weg.
Aber auch in FormCreate kann die Variable innerhalb von Test weg sein, da Embarcadero jetzt ausdrücklich gesagt hat, dass Variablen auch vor Ende ihres Gültigkeitsbereiches freigegeben wergen "können", vor allem, da du vor, als auch nach Test nicht nochmal darauf zugreifst.


Warum kommt jemand auf die saublöde Idee aus TStringList einen Pointer zu machen, aus dem nochmal ein Pointer auf einen bereits ungültigen Pointer gemacht wird, vor allem, da TStringList ein Objekt ist und somit bereits aus einem Pointer besteht? :freak:

Matthias. 5. Dez 2024 06:29

AW: Pointer Speicherinhalt geht verloren
 
Guten Morgen,

vielen Dank euch beiden, jetzt habe ich es verstanden.

Zitat:

Warum kommt jemand auf die saublöde Idee aus TStringList einen Pointer zu machen, aus dem nochmal ein Pointer auf einen bereits ungültigen Pointer gemacht wird, vor allem, da TStringList ein Objekt ist und somit bereits aus einem Pointer besteht?
Das war nur in dem Testprojekt :)

Danke!

Redeemer 5. Dez 2024 20:48

AW: Pointer Speicherinhalt geht verloren
 
Pointer haben keinen Speicherinhalt. Sie verweisen auf einen Speicherinhalt. Explizite Pointer (Pointer, PInteger usw.) verweisen immer auf fremden Speicherinhalt, ebenso in aller Regel alle Variablen vom Typ Klasse, die du nicht explizit selbst erstellt hast (
Delphi-Quellcode:
Wupp := TDi.Create()
). Selbst erstellte Instanzen musst du auch selbst freigeben, außer sie haben einen Besitzer (Owner, TObjectList<> usw.).


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.

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