![]() |
records im Speicher...
Es geht um dieses record:
Wieso sieht das im Speicher denn so ausund nicht so? Das ist zum einen Platzverschwendung und zum anderen richtig unpraktisch wenn man aus einer Datei lesen möchte. Gibts da nen Trick um das zusammenzuschieben? |
Re: records im Speicher...
Hast du mal Packed Record probiert ?
|
Re: records im Speicher...
Probier mal nicht record sondern
![]() Edit: Mann ist Corps heute wieder schnell ;-) |
Re: records im Speicher...
jo damit gehts!
Mann seid ihr schnell :D Danke! |
Re: records im Speicher...
Warum beantwortet ihr seine Frage nicht?
Der Delphi Compiler richtet die Felder des Records an Byte-Grenzen aus. Dies optimiert den Zugriff auf die Speicherbereiche, da die CPU sowieso immer 4 Byte (bei einer 32-Bit CPU) aus dem Speicher lädt. Sind die Felder an Byte-Grenzen ausgerichtet, ist es für die CPU "einfacher" die wirklich benötigten Bytes zu extrahieren. Der zusätzlich benötigte Speicherplatz ist heute vernachlässigbar. Die Ausrichtungsgrenze kann in den Compiler Optionen eingestellt werden. Will sicherstellen, dass kompatible Records auch mit einer anderen Ausrichtungsgrenze erstellt werden, kann man mit dem Schlüsselwort packed die Ausrichtung der Felder an Byte-Grenzen verhindern. Dabei kommt dann das raus, was du eigentlich erwartet hattest. |
Re: records im Speicher...
Deswegen hatte ich den Link noch in meiner Antwort drin. Da steht das auch nochmal kurz und knapp erklärt drin ;-)
|
Re: records im Speicher...
Den Link hab ich auch erst auf den zweiten Blick gesehen^^
Aber wenn wir schonmal dabei sind: Ist es schlimm mit
Delphi-Quellcode:
TID3v2FrameHeader = record
FrameID: array[0..3] of Char; Size: Integer; Flags: Word; end;
Delphi-Quellcode:
zu schreiben?
f.ReadBuffer(FHeader, 10);
|
Re: records im Speicher...
Vielleicht ist es so besser?
Delphi-Quellcode:
Grüße
f.ReadBuffer(FHeader,SizeOf(TID3v2FrameHeader));
Klaus |
Re: records im Speicher...
Ja, und wie. Stell dir vor, dein Compiler ändert seine Alignment-Grenzen auf zb 16 Byte. Dann ist deine Struktur wieder aufgebläht und nicht zum lesen zu gebrauchen... Daher benutze packed und sizeof!
|
Re: records im Speicher...
Nein Klaus, mit SizeOf ist es nicht besser, dann liests mir ja 2 Bytes zu viel weg.
Genau das war ja die Frage, ob es schlimm ist die zwei Bytes hinten dran nicht 'vollzulesen'. @Dax: joa, man kann ja nie wissen was dem Compiler auf einmal einfällt :lol: Mir ist schon klar dass es mit packed und SizeOf richtig ist, das mit den 10 war nur meine Notlösung. Funktioniert hat sie ja :D Hätt ich ja eigentlich selber draufkommen können... mit nem 64-Bit Compiler wärs wahrscheinlich schon schiefgegangen. |
Re: records im Speicher...
Zitat:
1. Antwort nicht gelesen - packed UND SizeOf. 2. Prinzip nicht verstanden - man kann einen Record nur lesen, wenn er identisch aufgebaut ist, d.h. wenn er in der Datei gepackt ist (meistens), dann ist auch im Programm NUR UND AUSSCHLIESSLICH packed korrekt. Bei unterschiedlichem Aufbau könnte man nur die Komponenten des Records einzeln einlesen. Gruss Reinhard |
Re: records im Speicher...
na weil aus
array[0..3] of Char + Integer + Word wird array[0..3] of Char + Integer + Word + 2 Bytes
|
Re: records im Speicher...
Wenn du packed angeben würdest, dann würde er kein Alignment durchführen bei dem Record und somit wäre der Record auch nicht 2 Byte grösser als du ihn definierst. Somit Frage nicht umgesetzt: packed und sizeof. Wurde aber schon gesagt.
@Luckie: Deine Ausführungen sind etwas schlecht formuliert, weil wenn er an Bytegrenzen ausrichten würde, dann bräuchte er kein Aligment, da Byte = 8 Byte. Sagen wir lieber, er richtet an DoubleWord-Grenzen aus. |
Re: records im Speicher...
Zitat:
|
Re: records im Speicher...
Zitat:
Wenn Du nur Bytes hast werden die nach Bytes ausgerichtet. Hast Du z.B. ein Byte und einen LongInt würde er den LongInt am nächsten "LongInt" vom an Beginn ausrichten - also am 4. Byte. Du hättest dann 3 Byte unverwendeten Speicher. "Byte", "unverw. Byte", "unverw. Byte", "unverw. Byte", "LongInt". <--- 4 Byte = SizeOf(LongInt) --->, LongInt. |
Re: records im Speicher...
Nö, er richtet es nach seiner eigenen Verarbeitungsgrösse aus. Da wir (noch) ein 32 Bit Delphi nutzen, richtet er es an einer durch 4 teilbaren Adresse aus und sorgt innerhalb des Records dafür, dass die Elemente genauso aligned werden. Ab D6 kann man mit dem Compilerschalter sogar angeben, welches Alignment er verwenden soll: $ALIGN [2|4|8]. Grundsätzlich nutzt er aber erstmal eine durch 4 teilbare Adresse.
D5 und zuvor war nur $ALIGN ON|OFF möglich, wobei ON = 4 war. D1 als 16 Bit Compiler lasse ich mal aussen vor. Zitat:
Delphi-Quellcode:
also eine Grösse von 5 bedeuten? Nein, leider nicht. Er ist 8 Byte gross. ABER: er richtet es immer nach dem grössten Element im Record aus. Weil z.B.:
TRec = record
i: longint; a: byte; end;
Delphi-Quellcode:
beide 16 Byte gross sind. Würde jetzt anstatt Double dort Word stehen, dann wäre Word das grösste Element und er würde bei beiden Records auf eine Grösse von 4 Bytes kommen.
TRec = record
i: double; a: byte; end; TRec2 = record i: byte; a: double; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:03 Uhr. |
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