Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#38

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 21:31
Das Problem ist die Referenz-Zählung für die Strings. Bei jeder Zuweisung wird der String an eine andere Speicheradresse geschrieben und die alte Speicheradresse wird als frei markiert.

Es taucht nicht auf, wenn man für die Eigenschaften Name und Vorname einen Getter benutzt
Delphi-Quellcode:
type
  TAdresse = class
  private
    FVorname: string;
    FName: string;
    function GetName: string;
    function GetVorname: string;
  public
    property Vorname: string read GetVorname write FVorname;
    property Name: string read GetName write FName;
  end;
Weiterhin taucht es nicht auf, wenn man die Adresse so zusammensetzt
Delphi-Quellcode:
function TFoo.GetFullName : string;
begin
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Und wenn man sich mal spasseshalber die Pointer auf die Variablen holt
Delphi-Quellcode:
function TTest.GetFullName : string;
var
  LVorname, LName : PChar;
begin
  LVorname := PChar( GetAdresse.Vorname );
  // jetzt zeigt der Debugger den korrekten Vornamen bei LVorname an
  LName := PChar( GetAdresse.Name );
  // ab jetzt steht in LVorname und LName der gleiche Wert, weil nun die Pointer an die gleiche Stelle zeigen
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Dieses ist aber eher Zufall, da die beiden Speicherstellen abwechselnd belegt werden, was wir mit folgendem Code überprüfen können
Delphi-Quellcode:
function TTest.GetFullName: string;
var
  LName1, LVorname, LName2 : PChar;
begin
{1}  LName1 := PChar( GetAdresse.Name );
{2}  LVorname := PChar( GetAdresse.Vorname );
{3}  LName2 := PChar( GetAdresse.Name );
end;
Hier die Inhalte jeweils nach der Codezeile
NrLName1LVornameLName2
{1}Lustig--
{2}LustigPeter-
{3}PeterLustigLustig
oder wenn man sich die Pointer-Adressen anschaut, dann (Beispielswerte, die ändern sich eh je nach Start)
NrLName1LVornameLName2
{1}$420C--
{2}$420C$422C-
{3}$420C$422C$422C
Oder hier einmal schön den Wechselreigen mit den Adressen bei der Zuweisung
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Vorname => A  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Name => A  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
Der Vollständigkeit halber sei noch erwähnt, dass dieses hier
Delphi-Quellcode:
function TTest.GetFullNameReverse: string;
begin
  Result := GetAdresse.Name + ' ' + GetAdresse.Vorname;
end;
natürlich einwandfrei funktioniert. Warum?
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Name => B  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Vorname => C  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
(funktioniert aber auch nur, weil der Speicherbereich noch nicht überschrieben wurde)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (29. Okt 2014 um 21:45 Uhr)
  Mit Zitat antworten Zitat