Verwirrendes sizeof mit short-datentyp
-
Hmm,
wieso gibt sizeof für folgende Struktur die korrekte Länge zurück:struct sBla { int nWert; char cStr[124]; };...nämlich 128 Byte, aber für diese Struktur nicht:
struct sVerwirrt { short nWert1; int nWert2; };...nämlich angeblich 8 Byte
Wie geht denn sowas? Und wie soll ich mit solchen Strukturen umgehen? Bin leider darauf angewiesen, ich lese hier irgendwelche kryptischen, fremden Binärdateien aus 
-
Das liegt am "Padding", das der Compiler einfügt - int-Werte lassen sich leichter verarbeiten, wenn ihre Adresse durch 4 teilbar ist, darum werden zwischen dem (2 Byte großen) nWert1 und nWert2 noch zwei Füllbytes reingequetscht.
(wenn du die Daten lückenlos benötigst, mußt du das Padding ausschalten - schau dich dazu mal nach der "#pragma pack" in der Compiler-Doku um)
-
Die Größe eines short int hängt von Compiler/Plattform ab. Ebenso bei long. Es gibt nur Grenzen die vom Standard vorgegeben sind. Deswegen gibt es Typen wie int8 etc. Stehen glaube ich in sys/types.h
-
Kleine Zwischenfrage:
Das bedeutet dann also, short wird, insofern das padding nicht abgeschaltet ist, gar nicht benötigt und man kann gleich int nehmen?MfG
-
Wenn es dir ums Padding geht, dann ja. Ab normalerweise nimmt man doch die Datentypen, die man braucht. Will man short, nimmt man short.
-
Dank euch schonmal. Nee, das "Padding" gilt dann wohl nur für Strukturen und sowas. sizeof(short) gibt auch weiterhin die "klassischen" 2 Byte zurück.
Problematisch war das Ganze für mich halt nur, weil ich sowas mache:MyFile.Read(&Struktur, sizeof(strukturtyp));Geht schön schnell, knallt aber super wenn dieses "Padding" eingreift

Ich werd mal versuchen das abzuschalten.
-
Naja, short belegt mit padding gleichviel Speicher wie int, nicht? Demnach kann man gleich auf short verzichten :|
MfG
-
Ein #pragma pack (1) wird vermutlich helfen. Ein #pragma pack (pop) hinter dem struct dürfte das dann wieder normalisieren.
#include <stdio.h> #include <time.h> #pragma pack (1) struct t{ short x; int y; }; int main(int argc, int **argv){ printf("%i\n", sizeof(struct t)); }zB liefert als Ausgabe 6.
-
@ceplusplus: Nicht unbedingt - Wenn du keine größeren Datentypen in der Struktur hast, lohnt es sich nicht, dort Lücken zu füllen. Und ein
struct sPoint{short x,y;};sollte auch nur die 4 Byte brauchen, die netto für die Unterbringung von 2 short-Werten nötig sind.@Cpp_Junky: Du mußt die Struktur-Definition in "#pragma pack" einschließen, dann wird sie lückenlos angeordnet (die genaue Syntax hängt vom verwendeten Compiler ab, mußt du mal nachschlagen).
-
Jo funktioniert, danke!

#pragma pack(1) struct sHeader { char cStr[124]; int nOffset; }; struct sEntry { short nItemCount; int nOffsetFirstItem; }; #pragma pack( )
-
Cpp_Junky schrieb:
...
Geht schön schnell, knallt aber super wenn dieses "Padding" eingreift...=> Deswegen ist das "Binärspeichern" fast immer ein blöde Idee (oder sagen wir mal: Es gibt in 99,99% der Fälle bessere Lösungen.
Da Du allerdings die Daten bereits vorgeliefert bekommst
Cpp_Junky schrieb:
...Bin leider darauf angewiesen, ich lese hier irgendwelche kryptischen, fremden Binärdateien aus ...Und wie soll ich mit solchen Strukturen umgehen?
1.) Verpass', demjenigen, der das verbockt hat eine kräftige Abreibung.
2.) Mach denselben Fehler nicht nochmal beim Einlesen !!!Merke Dir und verinnerliche: Das binäre Format von C++-Variablen im Speicher ist unspezifiziert !!!
Daraus folgt auch, dass Dir mit irgendwelchen Compilerschaltern/Pragmas/... nur kurzfristig weitergeholfen ist (Wer sagt denn, dass der "Schreiber" alles Padding abgeschaltet hat ?)Mein Tipp: Analysiere die vorkommenden Datenstrukturen und fülle dann sauber Feld für Feld - byteweise !
Gruß,
Simon2.
-
Oder nimm Ada. Das ist für so etwas am besten geeignet. So gräßlich die Sprache auch sonst sein mag, wenn man von C++ aus da drauf schaut.

-
Binäre Datenformate sind volle Kanne super!


-
An binären Datenformaten ist wenig auszusetzen (siehe z.B. MPEG), wenn sie sauber spezifiziert sind. Man sollte halt nur nicht structs drübermappen, es seidenn man kann mit bitgenauen Typen und ohne Padding arbeiten

-
hustbaer schrieb:
Binäre Datenformate ...
LordJaxom schrieb:
...binären Datenformaten ...
Naja, davon habe ich ja auch nicht gesprochen, sondern von
Simon2 schrieb:
...Das binäre Format von C++-Variablen im Speicher ...
Gruß,
Simon2.
-
Simon2 schrieb:
...
1.) Verpass', demjenigen, der das verbockt hat eine kräftige Abreibung.
2.) Mach denselben Fehler nicht nochmal beim Einlesen !!!
...Die Dateien sind anno 1995, der Typ ist längst über alle Berge

Binäre Datenformate sind volle Kanne super!

Binärdateien finde ich sehr viel eleganter als so eine ASCII Grütze a la XML o.ä., wo die halbe Datei aus Tags besteht und nach dem Einlesen noch geparsed werden muss. Binär musst du lediglich die passenden Speicher bereitstellen und kannst das Zeug in einem Rutsch einlesen. Problematisch ist halt das Handling der Datentypen und das Design des Dateiformats.
-
Hi,
Cpp_Junky schrieb:
...
Die Dateien sind anno 1995, der Typ ist längst über alle Berge :D...Der weiß schon, warum

Fairerweise muss man sagen, dass derlei Frickeleien vor 12 Jahren noch ziemlich "angesagt" und normal waren ... die Langzeitfolgen hat man eben erst später kennngelernt. Da hat man in den letzten 12 Jahren seeeehr viel dazugelernt.Wie schon gesagt: Du bist der lebende Beweis dafür, dass das eine schlechte Idee war.
Cpp_Junky schrieb:
...
Binärdateien finde ich sehr viel eleganter als so eine ASCII Grütze a la XML o.ä., wo die halbe Datei aus Tags besteht und nach dem Einlesen noch geparsed werden muss. Binär musst du lediglich die passenden Speicher bereitstellen und kannst das Zeug in einem Rutsch einlesen. Problematisch ist halt das Handling der Datentypen und das Design des Dateiformats.nochmal: Ich habe nicht von "ASCII" gesprochen ... aber Dein Problem ist anscheinend die unrealistische Priorisierung. Dein obiges Argument klingt wie
"Scheiß mit Reis ist einfach elegant ... ein wenig problematisch ist halt der Geschmack"
Gruß,
Simon2.
-
Ich versteh eure Binär-Angst nicht. Das erste Mal als ich sowas probiert habe, hab ich einen Loader für Quake2 Models geschrieben (MD2 Format) und hatte null Probleme damit. Wohl auch, weil Herr Carmack oder wer auch immer, sich da etwas mehr Gedanken drüber sein Dateiformat gemacht hat.
-
Einfach nur mit binären Dingen arbeiten, für jedes Dateiformat eine kleine Lib die sich um das Laden und Speichern kümmert, inklusive Versionsnummer in der Datei und einer Funktion zum Export in ASCII, falls mal der Quellcode verlorengeht oder schlimmeres. Hatte da auch noch nie Probleme.
XML hingegen ist der Tod der Intelligenz und Performanz.
-
Fellhuhn schrieb:
Einfach nur mit binären Dingen arbeiten, für jedes Dateiformat eine kleine Lib die sich um das Laden und Speichern kümmert, inklusive Versionsnummer in der Datei und einer Funktion zum Export in ASCII, falls mal der Quellcode verlorengeht oder schlimmeres. Hatte da auch noch nie Probleme.
Wenn du ein klar definiertes Format für die Binärdaten hast, ist das auch kein Problem. Allerdings hängt das interne Datenformat der C-Typen von zu vielen Faktoren ab, um da brauchbar zu sein.
(der Unterschied fällt allerdings erst auf, wenn du versuchst, deine Binärdateien in einem anderen System wieder einzulesen)