[C/C++] pb d'alignement inférieur à 32bits (resolu)

pb d'alignement inférieur à 32bits (resolu) [C/C++] - C++ - Programmation

Marsh Posté le 05-06-2004 à 21:49:59    

Bonsoir,
 
   Lorsque je compile cette structure de données, cette dernière occupe systématiquement 16 octets en mémoire alors que je m'attendais logiquement à en avoir seulement 14....  
 

Code :
  1. struct t_entete_fichier
  2. {
  3.  WORD signature;
  4.  DWORD taille_fichier;
  5.  DWORD reserve;
  6.  DWORD offset;
  7. };


 
Comme je souhaite ecrire au format binaire cette structure dans un fichier (entete de fichier bmp), il me faut trouver le moyen de lui faire occuper 14 octets en mémoire.
 
--edit : un pb d'alignement 32bits ? bizarre.
 
Merci de votre aide. :jap:


Message édité par xterminhate le 05-06-2004 à 21:59:00

---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 05-06-2004 à 21:49:59   

Reply

Marsh Posté le 05-06-2004 à 21:53:47    

C'est l'alignement, c'est normal
Pour aligner sur 1 byte ça dépend des compilos je pense.
 
Par exemple dans VC++5 c'est #pragma pack(1) pour l'activer, et #pragma pack() pour restaurer la valeur standard après la structure
 


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 05-06-2004 à 21:54:27    

Ca n'a rien de paranormal... C'est bien connu que la taille d'une structure n'est pas obligée de correspondre avec la somme des tailles de tous ses membres.
 
edit : grilled


Message édité par Ace17 le 05-06-2004 à 21:54:55
Reply

Marsh Posté le 05-06-2004 à 21:56:35    

Non je me doute bien que ce n'est pas paranormal, c'etait pour apater le client ;).
 
Cela dit, je compile avec minGW et je ne vois pas d'options de compilation pour resoudre mon pb. Il me faudrait juste reduire l'alignement à 16bits.
 
--edit : Parfait, #pragma pack() resoud mon pb.
 
Merci pour votre soutien et pour votre celerité !  :jap:


Message édité par xterminhate le 05-06-2004 à 21:59:36

---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 05-06-2004 à 21:59:26    

xterminhate a écrit :

Bonsoir,
 
   Lorsque je compile cette structure de données, cette dernière occupe systématiquement 16 octets en mémoire alors que je m'attendais logiquement à en avoir seulement 14....  
 

Code :
  1. struct t_entete_fichier
  2. {
  3.  WORD signature;
  4.  DWORD taille_fichier;
  5.  DWORD reserve;
  6.  DWORD offset;
  7. };


 
Comme je souhaite ecrire au format binaire cette structure dans un fichier (entete de fichier bmp), il me faut trouver le moyen de lui faire occuper 14 octets en mémoire.
 
--edit : un pb d'alignement 32bits ? bizarre.
 
Merci de votre aide. :jap:


 
une structure est toujours alignée sur un multiple du plus grand type la composant (ouhhh que c'est mal dit). Ici votre structure est donc alignée sur sizeof(DWORD). En fait, le compilo bourre là où c'est nécessaire (sauf instruction contraire) afin de conserver et l'alignement des membres de la structure et l'alignement de la structure elle-même dès fois que vous voudriez faire des malloc(n*sizeof(ma_structure)). Il ajoute donc parfois des octets entre les membres et/ou à la fin.
 
Bref, vous pouvez utiliser les #pragma pack en déplaçant signature en bas de la structure afin d'obtenir une structure sur 14 octets. Le petit problème est que vos performances ne vont pas être bonnes si vous allouez des tableaux de cette structure (et, si ma mémoire est bonne, cela plantera joliment sur une bécane SPARC).
 
edit: grilled itou


Message édité par docmaboul le 05-06-2004 à 22:00:42
Reply

Marsh Posté le 05-06-2004 à 22:01:35    

Exact.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 06-06-2004 à 00:01:23    

NB: tout ça n'est pas terrible : mapper une structure de données sur un format de fichier est mauvais. Définir un format de fichier, ensuite il faut définir une structure de données quitte à faire plus que des read/write (petites transformations)
 
pour le bpm, c'est ce que j'aurais fait : mes structures de données, après remplir les différents champs un par un

Reply

Marsh Posté le 06-06-2004 à 00:34:20    

Tu veux dire réaliser un read/write pour chaque champ de la (ou les) structure(s), plutot qu'un seul read/write pour la (ou les) structure(s) complete(s)? Ca eviterait de recourir au #pragma, mais je trouvais ca moins séduisant à coder.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 06-06-2004 à 00:36:06    

Ça limite les risques par contre :D


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 06-06-2004 à 00:39:42    

c'est un peu plus long, mais c'est le seul moyen de suivre une définition stricte d'un format de fichier : sinon tu te retrouves à tripatouiller le padding, et c'est la merde si la taille des données change en fonction de ton environnement.
 
surtout que les trucs binaires en C++, c'est bof ...
alors plutôt que faire un read, tu fais une classe, une fabrique, en pan pan, ça rends très bien

Reply

Marsh Posté le 06-06-2004 à 00:39:42   

Reply

Marsh Posté le 06-06-2004 à 09:42:08    

Et bien, il faut avouer que cette partie de programme n'a rien de C++ avec cette structure et ce read/write. D'accord, je vais en faire un objet avec une méthode spécifique pour la sérialisation binaire.
 
Sinon, c'est quoi dont "en pan pan" ???


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 06-06-2004 à 10:14:59    

rien ... dis toi juste que tes fichiers ne seront pas portables sur d'autres machines, d'autres compilateurs, d'autres environnement, etc

Reply

Marsh Posté le 06-06-2004 à 10:29:07    

Mon programme met en oeuvre une interface web, les images au format bmp seront affichables sur toute machine si le format est respecté. Par contre le code est effectivement spécifique de ma plateforme à cause de l'encodage binaire de WORD et DWORD (x86 Little Endian). Quoi que, je pourrais faire un effort pour utiliser htonl(), htons(), ntohl(), ntohs() ...ect.


Message édité par xterminhate le 06-06-2004 à 10:29:43

---------------
Cordialement, Xterm-in'Hate...
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed