Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
613 connectés 

  FORUM HardWare.fr
  Programmation
  C

  taille de structure == somme éléments?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

taille de structure == somme éléments?

n°1660690
ngkreator
Posté le 19-12-2007 à 15:41:52  profilanswer
 

Bonjour,
Pourquoi est-ce que ce programme suivant:
 

Code :
  1. #include <stdio.h>
  2. typedef struct
  3. {
  4.     unsigned short a;
  5.     unsigned long b;
  6. }structure_ab;
  7. typedef struct
  8. {
  9.     unsigned short a;
  10. }structure_a;
  11. typedef struct
  12. {
  13.     unsigned long b;
  14. }structure_b;
  15. int main(void)
  16. {
  17.     printf("struture a :  %u\n",sizeof(structure_a));
  18.     printf("struture b :  %u\n",sizeof(structure_b));
  19.     printf("struture ab : %u\n",sizeof(structure_ab));
  20.     return 0;
  21. }


 
Donne:
 

Citation :

structure a : 2
structure b : 4
structure ab : 8


 
et pas:
 

Citation :

structure a : 2
structure b : 4
structure ab : 6


 
Je vois mal où est mon erreur.

mood
Publicité
Posté le 19-12-2007 à 15:41:52  profilanswer
 

n°1660713
Taz
bisounours-codeur
Posté le 19-12-2007 à 16:11:38  profilanswer
 

il n'y pas d'erreur, il y a du bourrage ce qui est tout à fait normal quand ça n'est pas obligatoire.

n°1660716
spotaszn
Posté le 19-12-2007 à 16:16:59  profilanswer
 

Taz veut dire que ton compilo a préféré aligner le membre 'b' de type 'unsigned long' sur un multiple de 4 octets... Il a donc ajouté deux octets inutilisés après 'a'...
C'est parfois moins pénalisant en temps d'accès... c'est même parfois obligatoire.
 
Edit: il y a parfois aussi "bourrage" en fin de structure pour les mêmes raisons car le compilo ne doit pas créer de problème d'alignement dans les tableaux...


Message édité par spotaszn le 19-12-2007 à 16:18:52
n°1660717
ngkreator
Posté le 19-12-2007 à 16:19:20  profilanswer
 

Ah je connaissais pas le "bourrage". Et comment on fait si on veut lire un élément avec la fonction fread par exemple? On va lire 8 octets avec sizeof(structure_ab) en argument de fread. Alors qu'on veut en lire que 6.

n°1660720
Taz
bisounours-codeur
Posté le 19-12-2007 à 16:28:59  profilanswer
 

ngkreator a écrit :

Ah je connaissais pas le "bourrage". Et comment on fait si on veut lire un élément avec la fonction fread par exemple? On va lire 8 octets avec sizeof(structure_ab) en argument de fread. Alors qu'on veut en lire que 6.


Tu t'en occupes pas. Tu écris une struct et tu lis une struct. Tout le monde retrouve ses petits. C'est juste pas portable niveau format de fichier.

n°1660733
spotaszn
Posté le 19-12-2007 à 16:43:58  profilanswer
 

Tu as une directive "#pragma pack", si tu veux modifier le comportement de l'alignement... mais faut pas faire n'importe quoi avec (les push/pop sont alors bien pratiques).

n°1660744
Taz
bisounours-codeur
Posté le 19-12-2007 à 16:52:42  profilanswer
 

spotaszn a écrit :

Tu as une directive "#pragma pack", si tu veux modifier le comportement de l'alignement... mais faut pas faire n'importe quoi avec (les push/pop sont alors bien pratiques).


je l'attendais celle là  :fou:  
 
Toujours les mêmes à conseiller des trucs que personne n'utilisent sauf pour coder un kernel.
(Le premier qui me dit "c'est pour coller à une représentation binaire" il a perdu)
 
Une petite astuce, si c'est possible, c'est d'ordonner tes membres dans ta struct par taille décroissante et les grouper par type.

n°1660757
spotaszn
Posté le 19-12-2007 à 16:57:22  profilanswer
 

Merci à Taz pour cette mise en garde, on a vite fait de croire qu'on va coller à une représentation binaire mais on rencontre des problèmes d'endianess, donc de portabilité...
La question serait donc de savoir si le format de fichier est figé ou modifiable...

n°1660771
Taz
bisounours-codeur
Posté le 19-12-2007 à 17:07:21  profilanswer
 

Tu peux packer autant que tu veux sur sparc, ça ne donnera rien. Pour utiliser une représentation binaire portable, il faut la définir et l'implémenter en lisant octet par octet.
 
S'il s'agit d'un exercice, je pense que tout ça n'entre pas en compte. Il doit s'agir d'écrire un fichier et de le relire.

n°1660838
ngkreator
Posté le 19-12-2007 à 18:54:29  profilanswer
 

Un exercice? Non je m'amuse à travailler les fichiers bmp.  Pour l'instant mon programme fonctionne en lisant octet par octet (fgetc) le fichier bmp pour les insérer dans un tableau. Maintenant je veux faire ça avec des structures à la place des tableaux. Et j'essaye de lire et écrire mes structures (fread) en respectant le format bmp. C'est beaucoup plus pratique ... à 1ère vue.
 
Le problème c'est que je récupère des images bmp et c'est pas moi qui choisit le format d'écriture. Donc si j'ai une structure de 16 octets (alors que la somme des variables fait 14) qui représente l'entête du bmp et que fread m'écrit 16 octets (au lieu des 14 octets requis par le bmp) ça va pas aller.


Message édité par ngkreator le 19-12-2007 à 18:59:45
mood
Publicité
Posté le 19-12-2007 à 18:54:29  profilanswer
 

n°1660844
Joel F
Real men use unique_ptr
Posté le 19-12-2007 à 19:11:45  profilanswer
 

lit octet par octet et remplis ta structure. Forcer une binary representation == pas bien

n°1660848
ngkreator
Posté le 19-12-2007 à 19:21:14  profilanswer
 

Ok, dommage je trouvais fread pratique.

n°1660891
djobidjoba
Posté le 19-12-2007 à 22:14:33  profilanswer
 

il est préférable d'exporter et d'importer les champs de ta structure un par un en mettant au point un format d'enregistrement comme un simple tag/longueur/valeur.  
Tu pourra ainsi gérer par la même occasion des modifications de la structure comme l'ajout ou la suppresion d'un champs et les modification de types

n°1662504
Taz
bisounours-codeur
Posté le 23-12-2007 à 00:29:26  profilanswer
 

ngkreator a écrit :

Ok, dommage je trouvais fread pratique.


Tu peux utiliser fread, mais juste pas directement sur ta structure comme expliqué.

n°1662560
ngkreator
Posté le 23-12-2007 à 11:55:55  profilanswer
 

Ok donc en fait j'ai fait des fonctions qui lisent une structure et la mettent dans un tableau, dans le bon ordre et la bonne taille. Après c'est vrai que j'y avait pas pensé, je peux écrire le tableau en un seul coup avec fread pour l'écrire dans le fichier.
 

Code :
  1. unsigned char * convertir_header_tab(const t_header * header,char endianess)
  2. {
  3.     unsigned char *tab = NULL;
  4.     size_t i;
  5.     tab = malloc(HEADER_SIZE);
  6.     if(tab != NULL)
  7.     {
  8.         for(i = 0; i < sizeof(header->format); i++)
  9.             tab[OFFSET_HEADER_FORMAT+i]
  10.             = octet(header->format,sizeof(header->format),i+1,endianess);
  11.         for(i = 0; i < sizeof(header->size); i++)
  12.             tab[OFFSET_HEADER_SIZE+i]
  13.             = octet(header->size,sizeof(header->size),i+1,endianess);
  14.         for(i = 0; i < sizeof(header->reserved1); i++)
  15.             tab[OFFSET_HEADER_RESERVED1+i]
  16.             = octet(header->reserved1,sizeof(header->reserved1),i+1,endianess);
  17.         for(i = 0; i < sizeof(header->reserved2); i++)
  18.             tab[OFFSET_HEADER_RESERVED2+i]
  19.             = octet(header->reserved2,sizeof(header->reserved2),i+1,endianess);
  20.         for(i = 0; i < sizeof(header->offsetBits); i++)
  21.             tab[OFFSET_HEADER_OFFSETBITS+i]
  22.             = octet(header->offsetBits,sizeof(header->offsetBits),i+1,
  23.                     endianess);
  24.     }
  25.     return tab;
  26. }


 
Pour l'endianess je devais plutôt utiliser une constante définie par une marco du style:
 
#ifdef WINDOWS ENDIANESS 'l'
#elif LINUX ...
 
C'est une bonne idée?

n°1662565
Joel F
Real men use unique_ptr
Posté le 23-12-2007 à 12:26:46  profilanswer
 

deja l'endiannes ca depend pas de l'OS mais plutot de la famille du processeur :o
 
et non, c'est atroce. La bonne stratégie, à mon sens, est de sérialiser entiérement la SDD de manière endian-independant, et de reconstrurie les chsoes proprements à chaque fois.

n°1662573
ngkreator
Posté le 23-12-2007 à 12:59:58  profilanswer
 

Sérialiser la SDD?  
Ah pour l'endianess je savais pas. La différence serait plutôt PC <-> Mac alors. Comment prendre en compte ça pour que ça soit portable?
 
Pour être plus clair voilà ma démarche:
 
- lecture du fichier bmp et enregistrement des valeurs en prennant en compte l'endianess
- insertion des valeurs dans une structure
- lecture des valeurs à partir de la structure
- enregistrement du fichier bmp (à partir des valeurs) en prennant en compte l'endianess
 
Donc je ne fais la conversion qu'a l'écriture et la lecture.

Message cité 1 fois
Message édité par ngkreator le 23-12-2007 à 13:02:39
n°1662691
Emmanuel D​elahaye
C is a sharp tool
Posté le 23-12-2007 à 21:45:41  profilanswer
 

ngkreator a écrit :

Sérialiser la SDD?  
Ah pour l'endianess je savais pas. La différence serait plutôt PC <-> Mac alors.


avec les mac x86, non...

Citation :

Comment prendre en compte ça pour que ça soit portable?


On écrit du code portable. On définit un format de données indépendant de toute machine et on s'y tient. C'est pas plus compliqué que ça.
 
Ici, c'est le format BMP qui est la référence. Il faut faire ce qui est demandé, c'est tout. Si c'est bien fait (octet/octets, décalages...) c'est portable.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  taille de structure == somme éléments?

 

Sujets relatifs
Balise <sup> vs &sup1; - Changement de taille.Taille maximal d'un executable sous XP SP2
Calcul d'une somme un peu spéciale...[GTK] Probleme passage structure en argument signal
Pointeur en argument -> obtention de la taille de l'élément pointé?[MySql] Trigger structure conditionnelle [Résolu]
site marchand : achat de structure?Javascript et IE7 : probleme de taille !
Menu images, espace dans IE6 lorsqu'on agrandit la taille du texte[c] : Taille d'une structure != somme de ses élements?
Plus de sujets relatifs à : taille de structure == somme éléments?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR