Rückgabewertfehler von sizeof()-Funktion bei Strukturen

Daystalker

Grünschnabel
Hi Leutz,
bei dem Versuch eine Struktur in eine Datei zu speichern (mittels fwrite()-Funktion) verwende ich für die Größenangabe die sizeof()-Funktion. Hierbei übergebe ich die Struktur - und erhalte leider einen größeren Wert als die Struktur Daten aufgenommen hat.

Code:
struct sDaten
{
    int iZahl;
    char cZeichen;
    char szString[256];
};

Code:
sDaten *pMeineDaten;
pMeineDaten = new sDaten;

FILE *pFile;
    pFile = fopen("C:\\test.txt", "wb");
    fwrite(pMeineDaten, sizeof(sDaten), 1, pFile);
    fclose(pFile);

Dies ist dadurch zurückzuführen das bei Anlegen der Struktur mehr Speicherplatz benötigt wird als Daten aufgenommen werden - dadurch das die Daten an unterschiedliche Stellen im Arbeitsspeicher abgelegt werden.

Soweit das Problem! Sicherlich könnte ich jetzt "einfach" die einzelnen Größen "per Hand" zusammenzählen und damit arbeiten - das funktioniert.

Code:
int iSize = sizeof(int) + sizeof(char) + (sizeof(char) * 256);
    fwrite(pMeineDaten, iSize, 1, pFile);

Doch den Umstand jedesmal die Strukturgröße "per Hand" zu ermitteln ist nicht nur Zeitverschwendung sondern weist auch eine große Fehleranfälligkeit auf.

Wie kann ich das Problem lösen?

(Noch zwei Zusatzfragem: Wie kann ich mit AnsiStrings in der Struktur speichern/laden? Wie sollte ich den Speicher/Ladevorgang mit einem Stream bewerkstelligen (um die C-Funktionen zu vermeiden)?)

Vielen Dank im voraus...

Daystalker
 
moin


Du könntest die letzte Instanz deiner Struktur besonder Kennzeichnen und dann halt ermitteln wieviele schon davor stehen, oder meinst du das mit per Hand machen?


mfg
umbrasaxum
 
Moinsen umbrasaxum,
erstmal danke für die blitzschnelle Antwort.

Jedoch bin ich noch nicht bei "dem Problem" das ich mehrere Strukturen speichern möchte.

Es geht mir darum eine Struktur in eine (binäre) Datei zu speichern - ohne Overhead!

Zur Zeit liefert mir die sizeof()-Funktion einen Wert zurück, der größer ist als der tatsächlich benötigte Speicherplatz (durch die Variablen).

Das Speichern/Laden funktioniert auch mit dem Overhead, jedoch finde ich die Lösung weniger als annehmbar - alla "quick & dirty"...

In diesem Sinne...

Daystalker
 
moin


Achso jetzt hab ichs verstanden.
Also ist das * 256 das Problem.

Warum dann nicht so
Code:
int iSize = sizeof(int) + sizeof(char) + strlen(pMeineDaten->szString);
Oder
Code:
int iSize = sizeof(int) + sizeof(char) + (strlen(pMeineDaten->szString) * sizeof(char));


mfg
umbrasaxum
 
Die Grösse der Struktur ist für den Speicher optimiert. Du kannst bei MSVC mit einem #pragma pack(1) dieses Padding deaktivieren (nach der Struktur-Definition mit #pragma pack() wieder auf normal schalten). Dadurch würde die Struktur überall komplett gepackt sein. Bei anderen Compilern müsste es etwas Ähnliches geben.

Manchmal bringt auch das reine Umsortieren der Member im Struct bzw. bitweise packen (z.Bsp. Member-Variable als int name:8 deklarieren) schon einen Unterschied.

Ausser Dateigrössengewinn hast du davon eigentlich nichts. Die Zugriffe im Speicher werden langsamer sein, und auf exotischen Systemen klappt das gar nicht mehr (die müssen die Member aligned haben, aber auf "normalen" PCs geht das überall).

Tatsächlich macht sowas Sinn, wenn man auf verschiedenen Systemen bzw. mit verschiedenen Compilern dieselbe gepackte Struct verwendet. Dann kann es nämlich Unterschiede beim Padding geben. Auch für Netzwerke ist das dann sinnvoll.
Bei allem anderen ist es ziemlich überflüssig wegen eines oder 3 Bytes soviel Aufstand zu machen. Plattenspeicher gibt es praktisch ohne Ende.
 
Zurück