AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Verstehe das Verhalten der Records nicht.

Ein Thema von DevLinus · begonnen am 6. Dez 2017 · letzter Beitrag vom 6. Dez 2017
Antwort Antwort
Seite 1 von 2  1 2      
DevLinus

Registriert seit: 25. Apr 2017
26 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 08:31
Hallo zusammen,
geben ist Folgender Quellcode. An der Stelle wo CompareMem aufgerufen wird müssten die Records eigentlich Identisch sein. Die Methode gibt mir aber False zurück. Wenn ich die beiden Records auswerte scheinen alle Records gleich zu sein und KFMKey ist = 'XXX 148060'.

Nach dem ich es ein paar mal Debuggt habe, entschloss ich mich die Daten in eine Datei zu schreiben um zu prüfen ob die Binär gleich sind. Das Ergebniss ist das in der Datei jeweils der erste Wert steht und nicht der Neue. Dann habe ich noch folgende beiden Zeilen hinzugefügt und in der Datei wird es als XXX Test6001 gepseichert.
Code:
  lRec.SampleRecordInside.KfmKey := 'XXX 14806001';
  lRec.SampleRecordInside.KfmKey := 'XXX Test';
Muss ich die Record Felder Fillcharn? Ist dies das normale Verhalten? Wie Säubere ich das Recordfeld?

Code:
 
  TKFMKey = string[16];

  TSampleRecord = record
    Count : byte;
    KfmKey : TKFMKey;
  end;


  TOtherSampleRecord = record
    Count : byte;
    PaIsolatorKey : TKFMKey;
    PtIsolatorKey : TKFMKey;
  end;

  TMyRec = record
    aBoolean : boolean;
    KfmKey : TKFMKey;
    OtherSampleRecord : array[1..5] of TOtherSampleRecord;
    SampleRecordInside : TSampleRecord;
    SampleRecordOutside : TSampleRecord;
    SampleRecordMiddle : TSampleRecord;
    res : array[1..50] of byte;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn2Click(Sender: TObject);
var
  lRec : TMyRec;
  lRec2 : TMyRec;
  lStream : TFileStream;
  lStream2: TFileStream;
begin
  FillChar(lRec, sizeof(TMyRec),0);
  FillChar(lRec2, sizeof(TMyRec),0);
  lRec.KfmKey := 'XXX 14806001';
  lRec2.KfmKey := 'XXX 14806002';
  lRec.KfmKey := 'XXX 148060';
  lRec2.KfmKey := 'XXX 148060';

  if CompareMem(@lRec, @lRec2,SizeOf(TMyRec)) then // Müssten gleich sein sind sie aber nicht
    ShowMessage('Juhu')
  else
    ShowMessage('Fuck');
  lRec.SampleRecordInside.KfmKey := 'XXX 14806001';
  lRec.SampleRecordInside.KfmKey := 'XXX Test';
  ShowMessage(lRec.KfmKey);
  ShowMessage(lRec2.KfmKey);

  // Speichern der Testeinträge
  lStream := TFileStream.Create('C:\temp\test1a.dat',fmCreate);
  lStream.WriteBuffer(lRec,SizeOF(TMyRec));
  lStream.Free;
  lStream2 := TFileStream.Create('C:\temp\test2a.dat',fmCreate);
  lStream2.WriteBuffer(lRec2,SizeOF(TMyRec));
  lStream2.Free;
end;
Gruß,
DevLinus

Geändert von DevLinus ( 6. Dez 2017 um 08:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 08:59
Das Problem ist CompareMem auf einen shortstring.

Beim Zuweisen eines shortstrings wird nicht der "Rest" geleert.

Beispiel:

Delphi-Quellcode:
var
  s: string[16];
  i: Integer;
begin
  s := 'XXX 14806001';
  s := 'XXX 148060';
  for i := 1 to 16 do
    Write(s[i]);
end.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
DevLinus

Registriert seit: 25. Apr 2017
26 Beiträge
 
Delphi 10 Seattle Professional
 
#3

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 09:04
Das Problem ist CompareMem auf einen shortstring.

Beim Zuweisen eines shortstrings wird nicht der "Rest" geleert.

Beispiel:

Delphi-Quellcode:
var
  s: string[16];
  i: Integer;
begin
  s := 'XXX 14806001';
  s := 'XXX 148060';
  for i := 1 to 16 do
    Write(s[i]);
end.
Habe ich mir schon fast gedacht, aber warum wird mir im Debugger wenn ich die Variable Auswerte der Wert nicht angezeigt? Also muss ich jeden Short String, wo ich einen Kürzen String reinpacke vorher Fillcharn?
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 09:28
Zitat:
Habe ich mir schon fast gedacht, aber warum wird mir im Debugger wenn ich die Variable Auswerte der Wert nicht angezeigt? Also muss ich jeden Short String, wo ich einen Kürzen String reinpacke vorher Fillcharn?
Mach Dir eine Compare Function für die Records, mit CompareMem wirst Du in solchen Fällen immer auf die Nase fallen. Da spielt auch das Align eine Rolle.

Ausgehend von Align 4 (der default denke ich) sieht Dein Record im Speicher so aus:

Delphi-Quellcode:
TSampleRecord = record
    Count : byte;
    hidden : array[0..2] of byte; // Für das Align wird das vom Compiler eingebaut
    KfmKey : TKFMKey; // 17 byte
   hidden : array[0..2] of byte; // Für das Align wird das vom Compiler eingebaut
  end;
Kannst Du einfach mit sizeof(TSampleRecord) nachschauen. Habe es jetzt nicht getestet aber gehe davon aus das der Record 24 Byte gross ist.
Fritz Westermann
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.586 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 09:44
Ich würde dafür class operators benutzen:
Delphi-Quellcode:
TSampleRecord = record
    Count: byte;
    KfmKey: TKFMKey; // 17 byte
    class operator Equal(a: TSampleRecord; b: TSampleRecord): Boolean;
  end;

...

class operator TSampleRecord.Equal(a: TSampleRecord; b: TSampleRecord): Boolean;
begin
  Result := (a.Count = b.Count) and (a.KfmKey = b.KfmKey);
end;

...

var
  Test1, Test2: TSampleRecord;
begin
  ...
  if Test1 = Test2 then // einfach vergleichen
    ...
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 09:45
Also muss ich jeden Short String, wo ich einen Kürzen String reinpacke vorher Fillcharn?
Spontan würde ich sagen, das ist eine Möglichkeit.

Je nach verwendeter Delphi Version steht dir aber auch die Möglichkeit der Operatorüberladung zur Verfügung, wo du einfach Equals implementieren kannst, dann kannst du einfach schreiben: if Rec = lRec2 then
Mach Dir eine Compare Function für die Records, mit CompareMem wirst Du in solchen Fällen immer auf die Nase fallen. Da spielt auch das Align eine Rolle.
Hatte ich auch zuerst überlegt, aber wenn initial FillChar genutzt wird, sollte das kein Problem darstellen, weil auch die "Lücken" genullt werden.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 10:13
Hatte ich auch zuerst überlegt, aber wenn initial FillChar genutzt wird, sollte das kein Problem darstellen, weil auch die "Lücken" genullt werden.
Da wir die Delphi Version die der TE nutzt nicht kennen, ist das wohl der kleinste gemeinsame Nenner.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
DevLinus

Registriert seit: 25. Apr 2017
26 Beiträge
 
Delphi 10 Seattle Professional
 
#8

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 10:27
Danke! Mir haben eure Tipps weiter geholfen.

Delphi Version habe ich jetzt angegeben.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#9

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 15:27
Also muss ich jeden Short String, wo ich einen Kürzen String reinpacke vorher Fillcharn?
Spontan würde ich sagen, das ist eine Möglichkeit.
War es nicht so, dass es keine gute Idee ist, FillChar auf einen Record anzuwenden, in dem Strings enthalten sind, weil dadurch etwas kaputtgemacht wird (Referenzzählung oder so)?

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Verstehe das Verhalten der Records nicht.

  Alt 6. Dez 2017, 15:30
Bei ShortStrings geht das klar.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:57 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