[C++] Structure à taille non déterminée

Bonjour à tous, hier j’ai continué un de mes projets de programmation, et je suis tombé sur un problème concernant la structure ci-dessous :

[code]struct Electronic_Conf
{
char K,L,M,N,O,P,Q;
};

struct ChimicAtom
{
char  Number;
double  weight;
double  Electronegativity;
double  Fusion_Temp;
double  Ebulition_Temp;
Electronic_Conf Electron;
char  type;
char  Symbol[4];
char  Name[13];
};[/code]

Donc voilà, j’ai en C++ cette structure, qui selon mon chti fait celon mon pti cerveau
1

  • 8
  • 8
  • 8
  • 8
  • 7
  • 1
  • 4
    +13

58 octets.

Seulement voilà, un sizeof(ChimicAtom) me renvoit… 72 octets.

Surpri de ce résultat, je l’ai écrit dans un fichier

[code]AtomDump.bin (la structure venant du C++) :
0000000: 01cd cdcd cdcd cdcd e336 1ac0 5b20 f03f  …6…[ .?
0000010: cdcc cccc cccc 0040 0d0a d7a3 703d 3270  …@…p=2p
0000020: c0a4 703d 0d0a d79b 6fc0 0100 0000 0000  …p=…o…
0000030: 0001 4800 0000 4879 6472 6f67 656e 6500  …H…Hydrogene.
0000040: 0000 00cd cdcd cdcd cdcd 0d0a            …

Hydrogene.bin (la source venant du C#) :
0000000: 01e3 361a c05b 20f0 3fcd cccc cccc cc00  …6…[ .?..
0000010: 400a d7a3 703d 3270 c0a4 703d 0ad7 9b6f  @…p=2p…p=…o
0000020: c001 0000 0000 0000 0148 0000 0048 7964  …H…Hyd
0000030: 726f 6765 6e65 0000 0000 0a              rogene…[/code]

Hydrogene.bin ayant été généré par un code C# de ma composition.

En c++, on trouve des 0d et une série de cd en plus des données attendues.
J’ai fait passer le code sous deux compilateurs différents : celui de Visual Studio.net 2003 et gcc 3.2.3 (MinGW) pour un résultat identique.

Le problème, est lors de l’import de ces données, je ne peut pas passer par un bête
ifstream.Read((char*)&Atom, sizeof(ChimicAtom));
mais je doit remplir chaque champs 1 à 1 (ce qui est pas très propre et rajoute du code inutilement à mon goût).

D’où ma question : Pourquoi est-ce que j’obtiens une structure de 72 octets au lieu de mes 58 attendus (et qui correspondent à la taille d’un atome binaire écrit à partir du C#), où est-ce que j’ai absolument rien compris au C++ et qu’il va falloir que je me remette à étudier?

Note : je peux rajouter le code C# en cas de besoin

Moi, j’en attendais pas 58 octets :stuck_out_tongue:
C’est parfaitement normal. « On » appelle ça l’alignement.
Classiquement, les compilos C/C++ alignent les octets sur des frontières de 4 octets à partir du moment où on manipule autre chose que des chars.
Par exemple, une structure contenant un entier puis un char puis un entier pèsera 12 octets parce que le dernier entier sera implanté sur un multiple de 4 donc laissera un trou de 3 octets après le char. C’est vraiment un trou.

Si tu veux réduire cet alignement, alors tu peux utiliser des directives #pragma qui permettent de spécifier des alignements compacts, par exemple.

Voilà. Donc oui, remets toi à étudier :stuck_out_tongue:

Ouais en effet, va falloir que je fouille le sujet, merci de la réponse rapide ^^

Pour avoir une structure aligné au bit près tu peut faire un truc du genre :

struct ChimicAtom { char   Number : 3; double   weight : 17; double   Electronegativity : 23; ... };
Ici Number prendre les 3 premiers bits, weight les 17 suivant, …
Par contre il me semble que la taille de la structure globale sera aligné sur un multiple de 16 bit mais peut être même 32 vu que tu utilises des doubles : je n’ai aps assez manipulé ça pour te dire :stuck_out_tongue:
Si tu veux plus d’info, tu peut chercher « bit field » dans google :stuck_out_tongue:
Edit : un lien interressant qui résume l’utilisation des bit fields.

[quote name=‹ Clams › date=’ 17 Nov 2004, 15:33’]Pour avoir une structure aligné au bit près tu peut faire un truc du genre :

struct ChimicAtom { char Number : 3; double weight : 17; double Electronegativity : 23; ... };
Ici Number prendre les 3 premiers bits, weight les 17 suivant, …
Par contre il me semble que la taille de la structure globale sera aligné sur un multiple de 16 bit mais peut être même 32 vu que tu utilises des doubles : je n’ai aps assez manipulé ça pour te dire :stuck_out_tongue:
Si tu veux plus d’info, tu peut chercher « bit field » dans google :stuck_out_tongue:
Edit : un lien interressant qui résume l’utilisation des bit fields.
[right][post=« 303963 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Oui, mais non en fait !
Tu risques d’avoir 21 bit de « trucs » a la fin de ta structure, pour l’aligner… et ca c’est pour un system 32bit/64bit, si tu as besoin de plus… t’es mal !

Certain compilo, dont je ne donnerais pas les noms, on tendance a padder/aligner quand meme parce que bon voila quoi…

Donc, si tu veux etre sure de ton alignement, force avec des #pragma pack 0 et autres, pour t’assurer que ta structure est juste ce que tu veux qu’elle soit, ou faire ton padding toi meme, pour toujours tomber sur un nombre entier de byte/word/dword/qword (ca depend de la plateforme)…

ET SURTOUT : a n’utiliser que pour les structures que tu optimizes pour la tailles, car l’alignement des donnes a un impacte enaurme sur les perfs !