View Full Version : [C] Problema sizeof struct
Ho un problema con una sizeof di un record di questo tipo
struct Frame_header
{
unsigned short lf;//header lenght
unsigned char p;//semple precision
unsigned short x;//larghezza
unsigned short y;//altezza
unsigned char nf;//number of image component
void *components;// components
};
Il sizeof di questo record mi da come risultato 16...
ma non dovrebbe essere 12??
Invece se scrivo il record cosi:
struct Frame_header
{
unsigned short lf;//header lenght
unsigned short x;//larghezza
unsigned short y;//altezza
unsigned char p;//semple precision
unsigned char nf;//number of image component
void *components;// components
};
è 12.......
qualcuno sa dirmi perchè??
ilsensine
06-02-2006, 10:56
Per motivi di performance (e - su alcuni sistemi - di limiti di accesso non allineato), il compilatore inserisce alcuni campi di padding in modo che i campi successivi siano propriamente allineati. Quello che ottieni nella pratica è:
struct Frame_header
{
unsigned short lf;//header lenght
unsigned char p;//semple precision
char __padding1; //così x è allineato allo "short" (2 byte)
unsigned short x;//larghezza
unsigned short y;//altezza
unsigned char nf;//number of image component
char __padding2[3]; // così components è allineato a sizeof(void *); 4 byte su sistemi a 32 bit
void *components;// components
};
Con la tua seconda soluzione tutti i campi risultano allineati alla loro dimensione naturale, così nessun padding è necessario.
AnonimoVeneziano
06-02-2006, 10:57
Probabilmente c'entra l'allineamento della memoria
Ciao
E' una questione di allineamento nella memoria... Il compilatore cerca sempre di allocare le variabili da 4 byte sempre in una locazione multipla di 4 byte...mentre quelle da 2 byte in un multiplo di 2...
Quindi:
[0]
unsigned short lf;//header lenght
[2]
unsigned char p;//semple precision
[sarebbe 3, ma deve essere multiplo di 2, quindi 4]
unsigned short x;//larghezza
[6]
unsigned short y;//altezza
[8]
unsigned char nf;//number of image component
[in 9 non può, e nemmeno in 10, quindi 12]
void *components;// components
[Totale 16 byte]
[0]
unsigned short lf;//header lenght
[2]
unsigned short x;//larghezza
[4]
unsigned short y;//altezza
[6]
unsigned char p;//semple precision
[7]
unsigned char nf;//number of image component
[8]
void *components;// components
[Totale 12 byte]
1) sto usando windows XP e sto compilando con LCC-WIN32
2) Vorrei usare quel record per leggere da un file quindi non mi posso permettere padding.
3) Come posso Fare......
Grazie!!
2) Vorrei usare quel record per leggere da un file quindi non mi posso permettere padding.
Metti:
#pragma pack(1)
... definizione strutture ...
#pragma pack()
ilsensine
06-02-2006, 11:14
2) Vorrei usare quel record per leggere da un file quindi non mi posso permettere padding.
...stai leggendo un "void *" da un file!?
Un grande grazie ragazzi sapete sempre tutto!!!
tanto per espandere la domanda, il tag "#pragma" a cosa serve (oltre a questo)
che non l'ho mai capito??
Grazie Ancora !!
...stai leggendo un "void *" da un file!?
Appunto...stai leggendo un puntatore da un file ?!?!?
ah si scusate quello non l'ho tolto, solo la prima parte va letta direttamente, il puntatore va messo dopo, ma intanto senza il puntatore il problema e lo stesso!
Grazie ancora (non credo di essere in grado di fare la grandissima cavolata di leggere un puntatore da un file...)
ciao!!
tanto per espandere la domanda, il tag "#pragma" a cosa serve (oltre a questo)
che non l'ho mai capito??
#pragma serve, in generale, per passare al compilatore delle direttive speciali per gestire delle funzionalità specifiche dell'ambiente/compilatore/sistema operativo, come appunto l'allineamento dei dati o ad esempio la modifica dei warning o altro ancora.
Ribadisco!! un grandissimo Grazie!!
AnonimoVeneziano
06-02-2006, 11:36
Mmm, scusa, ma io non credo ci sia bisogno di #pragma per leggere una struttura da un file :confused:
Sbaglio? Io non l'ho mai fatto, se ci dobbiamo pure preoccupare dell' allineamento della memoria adesso (tra l'altro gestita in modo trasparente dal compilatore) .
Per me basta un :
fread(&struttura, sizeof(struttura), 1, file);
Se invece il file non è stato memorizzato tramite una fwrite ad una struttura dello stesso tipo consiglio un parsing del file e poi un assegnamento elemento per elemento
Ciao
Anonimo: dipendende da come è stato scritto il file, ovvio che se è stato scritto con lo stesso allineamento lo potrai leggere tranquillamente...ma se è stato scritto senza llineamento, magari da un altro programma, o addirittura da un altro dispositivo, dell'allineamento ci deve preoccupare...eccome...
Mmm, scusa, ma io non credo ci sia bisogno di #pragma per leggere una struttura da un file :confused:
Sbaglio? Io non l'ho mai fatto, se ci dobbiamo pure preoccupare dell' allineamento della memoria adesso (tra l'altro gestita in modo trasparente dal compilatore) .
Infatti ... normalmente puoi anche fregartene di come il compilatore allinea i dati nelle strutture, union, ecc...
Se una struttura con dati "allineati" dal compilatore la scrivi su file e poi la rileggi ... non c'è problema (beh, anche nel file avrai dei padding, ovviamente).
Ma se il file deve essere fatto in un certo modo ben preciso, allora l'allineamento ti deve importare eccome! ;)
Per fermare la disputa....
sto leggendo file jpeg, quindi conta l'allineamento!
ciao!!
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.