Einzelnen Beitrag anzeigen

choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#6

Re: Fehler beim Laden von Array of record aus Datei

  Alt 15. Jan 2004, 16:36
Zitat:
TFeld besteht aus Strings und Integer
Dann werden die Strings wahrscheinlich das Problem sein: Standardmäßig sind Strings in den heuten Versionen von Delphi (seit Delphi3?) als AnsiStrings abgelegt, zu denen in der OH folgendes zu finden ist:
Zitat von OH:
Eine AnsiString-Variable ist ein Zeiger, der vier Byte Speicherplatz belegt. Wenn die Variable leer ist (also einen String der Länge Null enthält), hat der Zeiger den Wert nil, und der String belegt keinen Speicherplatz. Ist die Variable nicht leer, zeigt sie auf einen dynamisch zugewiesenen Speicherblock[..].

Da es sich bei AnsiString-Variablen um Zeiger handelt, können zwei oder mehrere dieser Variablen auf denselben Wert zeigen
Solltest Du also einen Datentyp TFeld zB in der Form
Delphi-Quellcode:
type
  TFeld = record
    AnInt: Integer;
    AString: string;
    AnotherInt: Integer;
    AnotherString: string;
  end;
wird diese Struktur lediglich
Delphi-Quellcode:
  SizeOf(Integer)+SizeOf(string)+SizeOf(Integer)+SizeOf(string)
= 4 4 4 4
16 Bytes beanspruchen, obgleich Du vielleicht Strings der Länge 300 "in" ihnen ablegen wirst. Die Stringdaten selbst liegen, wie der OH zu entnehmen ist, auf dem Heap und nicht innerhalb dieser Struktur!

Solltest Du eine solche Struktur mit TStream.Write in einen Strom schreiben, werden tatsächlich nur die Daten innerhalb der Struktur, also, im Falle der Strings, Referenzen auf Speicherbereiche auf dem Heap geschrieben.

Zu den AnsiStrings schreibt die OH weiter
Zitat von OH:
Da dieser Speicherplatz [..] vollkommen automatisch verwaltet wird, erfordert er keinerlei Benutzercode.
und meint damit unter anderem: Es sollte keine Aussage darüber getroffen werden, wo auf dem Heap die tatsächlichen Daten liegen.

Wenn die "Logik von Delphi" entscheidet, dass die Daten nicht länger benötigt werden, und Du ein Exemplar von TFeld aus der Datei lädst, können die Referenzen auf Bereiche zeigen, die inzwischen nicht länger gültig sind. Aus diesem Grund sollten Deine Strings "komische Werte" aufweisen, während die Integers korrekt abgelegt und wieder geladen worden sind.

Eine kleine Anmerkung: Durch das Laden von Referenzen über direkten Speicherzugriff (zB TStream.Write) wird das Prinzip der Referenzzählung untergraben, so dass (möglicherweise erst zu einem späteren Zeitpunkt) Probleme bei der Verwendung von Strings auftreten können, obwohl die geschriebenen Referenzen auf gültige Bereiche auf dem Heap verweisen.
gruß, choose
  Mit Zitat antworten Zitat