Newsgroup: it.comp.os.linux.development
Titolo: fread. Problemi con struct

  -  rimuovi XXX x rispondere
 

 fread (&bmpfhead, sizeof(bmphead), 1, fp);
Molto probabilmente sizeof(struttura) != somma delle sizeof degli
elementi (perche' vengono aggiunti byte di padding per allineare
civilmente gli elementi). A seconda che la tua architettura sia little
endian o big endian i risultati cambiano.
Ciao
 David
-- 
<d.santinoli presso mi. flashnet. it>

> fread (&bmpfhead, sizeof(bmphead), 1, fp);
DS> Molto probabilmente sizeof(struttura) != somma delle sizeof degli
DS> elementi (perche' vengono aggiunti byte di padding per allineare
DS> civilmente gli elementi).
Togli il "molto probabilmente", è quello!
typedef struct tagBMPFHEAD {
	WORD    bfType;      /* Type of file. It must be BM */
	DWORD   bfSize;      /* Size of the file, in bytes */
	WORD    bfReserved1; /* Reserved; must be set to 0 */
	WORD    bfReserved2; /* Reserved; must be set to 0 */
	DWORD   bfOffset;    /* Offset of bitmap data */
} BMPFHEAD;=20
gcc "pacca" ai 32 byte per efficenza quindi hai in memoria
|--------|--------|
 [bfType] [pad   ]
 [bfSize         ] 
 [bfRes1] [brRes2] 
 [bfOffset       ]
Prova :
Il programmatore si attende 19978, 1516454, 0, 0, 54 ovvero la stringa
di simboli esadecimali (considerando  che le architetture intel tra le
farie cavolate hanno pure quella di essere little endian):
      |             |      |      |
0x0A4E 0xA623 0x1700 0x0000 0x0000 0x3600 0x0000
ma data la struttura che ha in memoria ottiene
      | PAD  |             |      |      |     
0x0A4E 0xA623 0x1700 0x0000 0x0000 0x3600 0x0000 0x????
                                                 non inizializzato
i bit sotto pad sono ignorati.
Al  riguardo riporto un  commento che  si trova  nei sorgenti  di talk
usati al dei dall'89:
talkd.c:        /* ovviamo cosi' alla stupidita' di quelli
talkd.c-         * di ucb che hanno fatto una dannatissima struttura
talkd.c-         * di 22 byte. Mai sentito che 680x0 arrotonda ai 4 byte ?
talkd.c-         * (Loro usavano il Vax780, scommetto)
talkd.c-         */
Il commento precede una modifica resasi necessaria per usare il talk di
berkeley su un LSX3020, macchina basata sul 68020.
--
Gian Uberto| main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Lauri      |                        David Korn, 1987 ioccc best one liner 
(aka saint)|-------------------------------------------------------------------
em@ail: 
sa...@eng.it
 ( vedere X-nospam nello header - see X-nospam in header )

Per un problema del genere una volta ho usato la direttiva pragma pack che
forza l'allineamento dei dati.
Esempio:
#pragma pack(1) /* allinea i dati al byte */
typedef struct{
...
} mystuct;
#pragma pack() /* ripristina allineamento di default */
Ciao
Alessandro Staltari.

 writes:
AS> Per un problema del genere una volta ho usato la direttiva pragma pack che
AS> forza l'allineamento dei dati.
AS> Esempio:
AS> #pragma pack(1) /* allinea i dati al byte */
AS> typedef struct{
AS> ...
AS> } mystuct;
AS> #pragma pack() /* ripristina allineamento di default */
Giusto, però  sarebbe meglio utilizzare tale struttura  solo per l'I/O
lasciando poi che  il programma funzioni con strutture  padded (a fine
I/O si  fa il trasferimento). Tutto  stà a vedere  se l'overhead della
copia viene compensato dagli accessi alla struttura padded o no...


ema wrote:

Sembra un problema di allineamento, come li hai scritti quei dati?
Ciao
Simone

 
ah, ok.  Grazie per l'info, pensavo che  questi  arrotondamenti  fossero
fatti solo per i bit.
Piuttosto, c'e` un modo per evitarle? Ad esempio qualche ottimizzazione?
E' un po' bruttino... gia` mi stanco con 5 campi, figuriamoci ne avessi
migliaia :-)


 
Gimp :-) Vado a leggere un BMP.
