Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie kann ich einen Record "echt" kopieren...? (https://www.delphipraxis.net/17969-wie-kann-ich-einen-record-echt-kopieren.html)

meggles 12. Mär 2004 08:49


Wie kann ich einen Record "echt" kopieren...?
 
Moin beisammen!
Mein Emailclient schafft mich noch ganz... :wall:
Eine Email wird durch folgenden Record beschrieben:

Delphi-Quellcode:
  TEmail = record
      id : integer;
      ordner_id : integer;
      von,
      replyto,
      an,
      cc,
      bcc : TIdEMailAddressList;
      betreff : string;
      Text : string;
      datum : TDateTime;
      prio : smallint;
      gelesen : Boolean;
      marke : boolean;
      beantwortet : boolean;
      eingang : boolean;
      schutz : boolean;
  end;
Die in der Listview angezeigten Emails enstprechend in einem Array:
Delphi-Quellcode:
  vEmailliste : array of TEmail;
Wird eine Email doppelt angeklickt, wird das Detailfenster geöffnet. Dieses enthält, um mit der Email arbeiten zu können eine Variable ebenfalls vom Typ TEMail.
Delphi-Quellcode:
vfNeueEmail := TfEmail.Create(Application);
  vfNeueEmail.vEmail := vemailliste[listviewEmails.itemindex];
Und nun zum Problem: Beim Öffnen, Schließen und erneuten Öffnen derselben Mail bekomme ich eine Zugriffsverletzung. Ich vermute auch, zu wissen, wieso: nach der Zuweisung verweist vfNeueEmail.vEmail auf den selben Wert wie vemailliste[listviewEmails.itemindex]. Schließe ich die Detailansicht, wird auch vfNeueEmail.vEmail freigegeben - und somit ja der Wert, auf den vemailliste[listviewEmails.itemindex] verweist. Erneutes Öffnen der Email bedeutet also einen Zugriff auf einen Arraywert, den es nicht mehr gibt. Wie also kann ich vEmail eine "echte Kopie" geben?

Danke im Voraus - schönen stressfreien Tag :-D

Simon

Jens Schumann 12. Mär 2004 09:16

Re: Wie kann ich einen Record "echt" kopieren...?
 
Nach
Delphi-Quellcode:
vfNeueEmail.vEmail := vemailliste[listviewEmails.itemindex];
enthält vfNeueEmail.vEmail eine Kopie des Records aus vemailliste. Bevor Du vfNeueEmail freigibst
musste den Record wieder in das Array schreiben.
Delphi-Quellcode:
vemailliste[listviewEmails.itemindex]:=vfNeueEmail.vEmail
vfNeueEmail.vEmail enthält einen Record. Records werden nicht freigeben.

CenBells 12. Mär 2004 10:22

Re: Wie kann ich einen Record "echt" kopieren...?
 
Zitat:

Zitat von Jens Schumann
Nach
Delphi-Quellcode:
vfNeueEmail.vEmail := vemailliste[listviewEmails.itemindex];
enthält vfNeueEmail.vEmail eine Kopie des Records aus vemailliste. Bevor Du vfNeueEmail freigibst
musste den Record wieder in das Array schreiben.
Delphi-Quellcode:
vemailliste[listviewEmails.itemindex]:=vfNeueEmail.vEmail
vfNeueEmail.vEmail enthält einen Record. Records werden nicht freigeben.

Hallo,

das macht doch auch keinen sinn. Wenn du sagst, daß vfNeueEmail.vEmail eine kopie enthalten würde, müsstest du den record nicht zurück ins array schreiben - der Record würde ja immer noch im Array stehen.
Mit echt kopieren würde ich mir mal die methode assign einer stringlist anschauen. Da siehst du, daß die wert wirklich "kopiert" werden.
das müsste also so aussehen
Delphi-Quellcode:
procedure copyEmail(var Source, Dest: TEmail);
begin
  Dest.id := Source.id ;
  // etc
end;
musst natürlich vorher sicher stellen, daß Dest auch schon alloziiert wurde.

Gruß
Ken

Jens Schumann 12. Mär 2004 10:34

Re: Wie kann ich einen Record "echt" kopieren...?
 
Zitat:

Zitat von CenBells
das macht doch auch keinen sinn. Wenn du sagst, daß vfNeueEmail.vEmail eine kopie enthalten würde, müsstest du den record nicht zurück ins array schreiben - der Record würde ja immer noch im Array stehen.
Mit echt kopieren würde ich mir mal die methode assign einer stringlist anschauen. Da siehst du, daß die wert wirklich "kopiert" werden.
das müsste also so aussehen
Delphi-Quellcode:
procedure copyEmail(var Source, Dest: TEmail);
begin
  Dest.id := Source.id ;
  // etc
end;
musst natürlich vorher sicher stellen, daß Dest auch schon alloziiert wurde.

Ein Record ist kein Object Da wird nichts alloziert oder so. Du gehst davon aus, das mit vfNeueEmail.vEmail:=vemailliste[listviewEmails.itemindex]; eine Referenz auf den Record übergeben wird. Dem ist nicht so. Gerade weil vfNeueEmail.vEmail eine Kopie enthält muss der Record zurück ins Array geschrieben werden.
Hier ein Beispiel:
Delphi-Quellcode:
var
  a : Array of Integer;
  b : Integer;
...
  a[1]:=42;
  b:=a[1];
  // b enthält jetzt 42 und a[1] auch
  b:=73;
  // b enhält jetzt 73 und a[1] enthält jetzt 42
  // Damit a[1] den Wert von b enthält muss jetzt folgendes passieren
  a[1]:=b;
In dem Beispiel entspricht vemailliste a und vfNeueEmail.vEmail b.
Ich hoffe jetzt ist es deutlich geworden.

CenBells 12. Mär 2004 10:44

Re: Wie kann ich einen Record "echt" kopieren...?
 
Hallo,

aber wenn ich meggles verstanden habe, kommt das problem beim erneuten zugriff auf das element des arrays... Und dort sollte ja immernoch der ursprüngliche wert drinstehen, oder etwa nicht?
Wenn da immer noch der ursprüngliche wert drinsteht, dann sollte doch aber kein fehler beim erneuten öffnen kommen, oder?
Das ein Record kein Objekt ist, war mir auch vorher schon klar, aber kann es in diesem fall nicht irgendwie damit zusammenhängen, daß die TIdEmailAddresslisten freigegeben werden, wenn die instanz von vfNeueEmail freigegeben wird und damit auch das record nicht mehr referenziert wird? Wobei, das wäre ja bald java like, daß man sich um speicher nicht mehr kümmern müsste *G* Also, was passiert mit den instanzen von TIdEmailAdressList?

Gruß
Ken

Jens Schumann 12. Mär 2004 10:49

Re: Wie kann ich einen Record "echt" kopieren...?
 
Zitat:

Zitat von CenBells
aber wenn ich meggles verstanden habe, kommt das problem beim erneuten zugriff auf das element des arrays... Und dort sollte ja immernoch der ursprüngliche wert drinstehen, oder etwa nicht

Das glaube ich nicht. Ich glaube, dass die SV an anderer Stelle kommt und meggles nur glaubt sie würde da auftauchen. In dem Array muss der alte Wert stehen.

Ein grundsätzlichen Fehler von meggles ist auch die Verwendung eines dyn. Array anstatt TList oder einer verketteten Liste oder ähnliches.

Neulich hat Luckie hier geschrieben, dass er festgestellt hätte, dass ein dyn. Array freigeben wird, wenn der Gültigkeitsbereich verlassen wird. Ich als erstes in diese Richtung suchen.

meggles 12. Mär 2004 11:07

Re: Wie kann ich einen Record "echt" kopieren...?
 
Hi,
danke erstmal für Eure Hilfe.
Delphi-Quellcode:
  vfNeueEmail := TfEmail.Create(Application);
  vfNeueEmail.vEmail := vemailliste[lvemails.itemindex];
  showmessage(vfNeueEmail.vemail.betreff);
1. Emailöffnen: alles bestens, Showmessage zeigt mir den Betreff an.
2. Email schließen.
3. Email wieder öffnen: nix Showmessage, Schutzverletzung. Mauszeiger auf "...vemail.betreff" zeigt auch Schutzverletzung an.
Das passiert mit jeder Email, die ich shcon einmal offen hatte, also siehts doch danach aus, dass ich mir der Reihe nach die Arrayeinträge abschieße. Ou Mann!
Noch irgendeine Idee?
Zitat:

Ein grundsätzlichen Fehler von meggles ist auch die Verwendung eines dyn. Array anstatt TList oder einer verketteten Liste oder ähnliches.
@Jens: Wieso grundsätrzlicher Fehler?

Vielen Dank!

Simon

stoxx 12. Mär 2004 11:57

Re: Wie kann ich einen Record "echt" kopieren...?
 
Code:
vfNeueEmail := TfEmail.Create(Application);
vfNeueEmail.vEmail^ := vemailliste[listviewEmails.itemindex]^;

meggles 12. Mär 2004 12:31

Re: Wie kann ich einen Record "echt" kopieren...?
 
ui ui ui, Stoxx,
kannst Du mir da ein, zwei Zeilen Erklärung dazuschreiben? Ich verstehe zwar, dass Du jetzt mit Pointern arbeitest, aber - wieso...? :shock:
THX!
Simon

Jens Schumann 12. Mär 2004 12:45

Re: Wie kann ich einen Record "echt" kopieren...?
 
Hallo meggles,
bitte zeige mal etwas mehr Code. Evt. die komplette unit.

Ich persönlich halte von dyn. Array's gar nichts. Das ist so VB-mäßig.
Deshalb habe ich hier von einem grundsätzlichen Fehler geschrieben.

Ich würde die eMail Daten auch nicht als Record, sondern als Objekt mit TList
verwalten. Dann wird nämlich tatsächlich "nur" eine Referenz übergeben.
Dieses ganze Zeug mit Kopien und SV gibt es dann nicht mehr.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:21 Uhr.
Seite 1 von 2  1 2      

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