Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Größe in Bytes eines Arrays bestimmen (https://www.delphipraxis.net/118418-groesse-bytes-eines-arrays-bestimmen.html)

gargano 7. Aug 2008 12:25


Größe in Bytes eines Arrays bestimmen
 
Hallo,

ich habe ein verschachteltes Array von Records etwa von diesem Ausmaß

Delphi-Quellcode:
type
     TCalibPoint = record
                Active : Boolean;
                x,y   : Single;
     end;

     TCalibArray = array of TCalibPoint;

     TCalibData = record
                  NoOfRegItems : Integer;
                  RegItems    : Array of Double;
                  NoOfCItems  : Integer;
                  CalibArray  : TCalibArray;
     end;

     TCalibrationArray = array of TCalibData;
Die Arrays werden dynamisch erzeugt.
Wie kann ich die Größe von TCalibrationArray in Bytes ermitteln, ohne mit sizeof zu arbeiten ?
Sizeof liefert nur die Größe des Pointers also 4.

Ok, ich kann mit Length arbeiten und dann Length*Length*Sizeof usw... aber gibt es einen einfacheren Weg ?
Die Anzahl der Bytes brauche ich für LoadfromStream in der DB.

Viele Grüße
gargano

Medium 7. Aug 2008 13:32

Re: Größe in Bytes eines Arrays bestimmen
 
Zitat:

Zitat von gargano
aber gibt es einen einfacheren Weg ?

Nein. Es gibt zu Arrays und Records kaum Metainformationen, so auch keine automatisch ermittelte Größenangaben. Länge*SizeOf(EinElement) ist bei dynamischen Arrays soweit ich weiss der einzige Weg. Bei solchen innerhalb eines Records müsstest du dann wtwas der Art "SizeOf(Record)-SizeOf(Record.MyDynArray)+Length(Record.MyDynArray )*(SizeOf(Record.MyDynArray[0]))" basteln. Etwas mehr Möglichkeiten gibt es mit published Membern von Klassen, deren Typen und Namen man sich z.B. zur Runtime via RTTI beschaffen kann, wodurch man die Größenberechnung mehr oder weniger allgemein halten könnte, aber das ist auf keinen Fall weniger Aufwand, und eben auch nur mit Klassen möglich. (Ich weiss nicht genau wie es sich mit den erweiterten Records späterer Versionen als Delphi 7 genau verhält. Evtl. gibt es da ja etwas mehr RTTI zu.)

himitsu 7. Aug 2008 13:47

Re: Größe in Bytes eines Arrays bestimmen
 
als Erstes kommt es mal darauf an, wie du die Größe deiner Arrays im Stream speicherst.
(gibt da ja mehrere Möglichkeiten, welche nicht immer die selbe Größe besitzen)

im Endefekt kommst du aber um ein paar Length, eventuell in Verbindung mit ein paar SizeOf/RTTI nicht herrum.

gargano 7. Aug 2008 13:59

Re: Größe in Bytes eines Arrays bestimmen
 
Vielen Dank für die Antwort, das habe ich befürchtet

Gargano

Apollonius 7. Aug 2008 18:34

Re: Größe in Bytes eines Arrays bestimmen
 
Natürlich gibt es RTTI für Records und dynamische Arrays, schließlich müssen diese finalisiert werden. Das automatische Berechnen der Größe sollte also durchaus möglich sein.

himitsu 8. Aug 2008 09:23

Re: Größe in Bytes eines Arrays bestimmen
 
wie gesagt, erstmal müßte man wissen in welchem Format du die Arraydaten (in dem Stream) speichern willst und dann könnte man auch vorausberechnen welche Größe das ergibt.


aber mal zu den Typen...

zwecks der Speicherung macht es sich bestimmt besser auf feste Typengrößen zu setzen und die Speicherausrichtung zu eliminieren
(z.B. kan man die Speicherausrichtung änder und Integer war unter Delphi 1 16 Bit, jetzt ist es 32 Bit und in einem 64-Bit-Delphi wird es wohl 64 Bit sein)

und da Delphi ja bei seinen Arrays die Größe mit speichert, is es da nötig dieses nochmals im Record anzugeben.
(ok, so kann man aunfach auf TCalibData.NoOfRegItems, statt auf Length(TCalibData.RegItems) zugreifen)
und sind diese Werte immer identisch? (bräuchte man nur NoOf.. speichern ung könnte Length(array) einfach ignorieren)
Delphi-Quellcode:
TCalibPoint = packed Record
  Active : Boolean;
  x, y  : Single;
end;

TCalibArray = packed Array of TCalibPoint;

TCalibData = packed Record
  //NoOfRegItems : LongInt;     entspricht doch Length(TCalibData.RegItems)
  RegItems      : packed Array of Double;
  //NoOfCItems  : LongInt;     entspricht doch Length(TCalibData.CalibArray)
  CalibArray    : TCalibArray;
end;

TCalibrationArray = packed Array of TCalibData;

wenn ich jetzt einfach mal ignorieren, daß die Arraylänge schon im Record (NoOf...) gespeichert ist, dann so ... incl. der Längenangaben der Array's (je ein LongInt)
Delphi-Quellcode:
type TCalibPoint = packed Record
    Active : Boolean;
    x, y  : Single;
  end;

  TCalibArray = packed Array of TCalibPoint;

  TCalibData = packed Record
    NoOfRegItems : LongInt;  
    RegItems    : packed Array of Double;
    NoOfCItems  : LongInt;  
    CalibArray  : TCalibArray;
  end;

  TCalibrationArray = packed Array of TCalibData;

var CalibrationArray: TCalibrationArray;
  Size, i, i2: LongInt;


// Length(CalibrationArray)
// CalibrationArray[i].NoOfRegItems CalibrationArray[i].NoOfCItems
Size := SizeOf(LongInt)
  + Length(CalibrationArray) * 2 * SizeOf(LongInt);

for i := 0 to High(CalibrationArray) do begin
  // Length(CalibrationArray[i].RegItems)
  Inc(Size, SizeOf(LongInt));

  // CalibrationArray[i].RegItems
  Inc(Size, Length(CalibrationArray[i].RegItems) * SizeOf(Double));

  // Length(CalibrationArray[i].CalibArray)
  Inc(Size, SizeOf(LongInt));

  for i2 := 0 to High(CalibrationArray[i].CalibArray) do begin
    // Length(CalibrationArray[i].CalibArray[i2])
    Inc(Size, SizeOf(LongInt));

    // CalibrationArray[i].CalibArray[i2]
    Inc(Size, Length(CalibrationArray[i].CalibArray[i2]) * SizeOf(TCalibPoint));
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:26 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