IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Même élément d'une structure mais size différents ?


Sujet :

C

  1. #1
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut Même élément d'une structure mais size différents ?
    Bonjour
    J'aurais besoin de quelque éclaircissement sur certaines informations que je vais énoncer ci-dessous.
    j'ai remarqué que deux structures ayant les mêmes données, en strictement pas la même taille et cela me force à les réaligner.
    Dans l'exemple plus en bas, la différence de taille est elle dû au fait que sizeof prend en compte l'espace physique de la structure & l'espace inutilisé qui pointe sur les types de la structure ? ou c'est juste autres choses et pourquoi ?
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    #include <stdio.h>
    #include <stdlib.h>
     
    // Exemple 1
    struct st_ExpA{
     
    	   char tA[20];
    	   char tB[10];
    	   char tC[5];
    	   long lA;
    	   long lB;	
    }A;
    // Même structure Exemple 1
    struct st_ExpB{
     
           char tA[20];
    	   long lA;
    	   char tB[10];
    	   long lB;	
    	   char tC[5];	
    }B;
    //Forçage d'alignement
    struct ts_Alig{
     
    	unsigned long pos_X: 16;
    	unsigned long pos_Y: 16;
    }Al;
     
    //Programme principale de teste
    int main( void ){
     
    	printf( "Size A =\t%d\n", sizeof( A ) );
    	printf( "Size B =\t%d\n", sizeof( B ) );
     
    	return( 0 );
    }
    (Après compilation en remarque que la seconde structure de donnée prend plus d'espace mémoire).
    Merci d'avance pour vos réponses et à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  2. #2
    En attente de confirmation mail

    Profil pro
    Inscrit en
    Septembre 2013
    Messages
    639
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 639
    Points : 2 347
    Points
    2 347
    Par défaut
    Peut-être le char t[5] est-il aligné sur un nombre pair d'octets s'il n'est pas le dernier du struct ?

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    En commentant les attributs, tu trouves ta solution

    En gros sur une plateforme 32bits, il y a des alignements sur des multiples de 4 octets (32bits == 4 octets)

    Pour la structure st_ExpA, tu vas perdre un octet entre lA et lB, pour arriver à 44 octets au lieu de 43.
    tA + tB + tC + lA = 39 octets.
    Mais le compilateur l'aligne sur 40 octets (10*4)

    Pour la structure st_ExpA, c'est plus compliqué
    tA + lA = 24 octets (4*6) pas de problèmes

    tA + lA + tB = 34 octets, aligné sur 36 (9*4)

    tA + lA + tB + lB = 40 octets (4*10) pas de problèmes

    tA + lA + tB + lB + tC = 45 octets, aligné sur 48 (12*4)


    Et au passage c'est #pragma pack qui permet de faire de l'alignement

  4. #4
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 62
    Points : 162
    Points
    162
    Par défaut
    Bonjour,
    Foetus a tout bon! C'est pour ça qu'il vaut mieux en général classer les membres par taille décroissante dans les structures afin de minimiser se phénomène au milieu de la structure.

  5. #5
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par foetus Voir le message
    En commentant les attributs, tu trouves ta solution
    Bonsoir
    Merci et il me semble l'avoir compris , mais ceci dit la question était de savoir si sizeof prenait en compte l'alignement des espaces inutilisés avec le reste des données et il me semble que ça soit le cas, et je suis d'avis sur la déclaration décroissante des types pour un alignement correct.
    Et pour un alignement comme ce qui suit , on à pas forcement besoin de #pragma pack ? si
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    #include <stdio.h>
    #include <stdlib.h>
     
    // Exemple 1
    struct st_ExpA{
    	   char: 4;
    	   long: 4;
     
    	   char tA[3];
    	   char tB[1];
    	   long lA;
     
    }A;
    // Même structure Exemple 1
    struct st_ExpB{
    	   char: 1;
    	   long: 1;
     
           char tA[3];
    	   long lA;
    	   char tB[1];
    }B;
     
    //Programme principale de teste
    int main( void ){
     
    	printf( "Size A =\t%d\n", sizeof( A ) );
    	printf( "Size B =\t%d\n", sizeof( B ) );
     
    	return( 0 );
    }
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Bonjour,
    si je me souviens bien, sizeof retourne la taille en octet de l'objet fourni.
    Si c'est un tableau, c'est l'ensemble de ses éléments.
    Si c'est une structure, c'est la différence entre le premier et le dernier octet.

    Dans mon souvenir, si s est une structure (du type struct S) ayant membre pour dernier membre, on doit avoir sizeof s = sizeof S >= &s.membre +sizeof(s.membre) (car il peut y avoir du padding au bout.)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut Même élément d'une structure mais size différents ?
    Bonjour
    Ok. Je pense avoir compris. Les types s'alignent au bord des mots (4 octets) selon les règles d'alignement des variables et les structures toujours en début ou fin de périmètre ce qui fait que sizeof connaît la taille des données tout en prenons en compte la représentation physique de la structure mais également les zone inutilisé ce qui donne pour une structure similaire, des tailles différentes.
    Pour essayer de comprendre ce que j'avance, la première structure dans le dernier exemple à une taille de 8 octets parce que les caractères s'alignent sur les 4 premiers octets et le long à la suite. Quant à la deuxième structure elle prend un peu plus d'octets car, elle aligne avant tout 3 octets avec une zone vide d'un octet puis les 4 octets du long et viens ensuite un octet pour le dernier membre avec à la suite 3 octets vide (inutile, en claire c'est du gaspillage pour rien) et la question que je me pose pourquoi c'est octet en plus pour rien est-ce volontaire.

    Je vais peut-être dire une connerie mais, y aurait-il pas une option autre que "-wpadded" car ,au lieu de savoir si une structure est alignée ou pas on peut juste demander au compilateur de les réaligner.
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    La réponse est simple
    Le processeur ne travaille qu'avec des morceaux de 4 octets (32 bits) ou 8 octets (64 bits)
    C'est plus simple pour lui de commencer un attribut au prochain multiple au lieu qu'il soit à cheval

    Exemple: En 32 bits, une structure avec A un tableau de 3 chars (3 octets) et B un int (4 octets)
    Cas facile (un truc de ce goût): || A0 : A1 : A2 : Bourrage +1 || < - : - : B : - > ||
    Cas pas facile: || A0 : A1 : A2 : < - || - : B : - > : Indéfini ||

    Alignement en mémoire

  9. #9
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut Même élément d'une structure mais size différents ?
    Oui tu as raison, mais bon c'est quand même du gaspillage d'octet
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ce n'est pas nécessairement du gaspillage d'octets : ça peut être un gain en vitesse pour ton processeur qui va accéder à ton champ en une lecture sans avoir à faire des masques et des décalages. Si le padding était juste un gaspillage d'octets, ça n'existerait pas.

  11. #11
    Membre régulier
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Points : 77
    Points
    77
    Par défaut
    Avec GCC, tu peux aussi utiliser l'attribut packed sur tes structures et enum. L'attribut s'utilise comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    typedef struct{
    // Tes champs
    } __attribute__ ((__packed__)) Struct1;
    L'attribut va alors spécifier que tu souhaite que tout les éléments de Struct1 soient stockés de manière compact, donc en clair pas de padding. Attention avec l'utilisation de cet attribut qui vient avec une potentielle baisse de performance du programme en temps d’exécution, puisque le processeur va passer plus de temps a accéder/chercher les champs de la structure. Personnellement, j'ai benmarké mon appli avec cet attribut sur différente machine et la différence de temps d’exécution était vraiment minime. Après je ne l'utilise que peu, disons sur 25% de mes structures, il ne sert a rien de ralentir le programme juste pour gagner quelques kilo-octets.

  12. #12
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut Même élément d'une structure mais size différents ?
    Citation Envoyé par Wizard50 Voir le message
    il ne sert a rien de ralentir le programme juste pour gagner quelques kilo-octets.
    Bonjour
    Oui, sert mais dans mon cas cela m'est utile car, je compte gérer une zone mémoire indépendamment du mécanisme actuel, et à terme je pense même en tiré certain avantage et merci pour l'info sur l'attribut packed je n'avais jusque-là pas eu connaissance de ça
    Merci et à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Sache tout de même qu'il y a énormément de surcout à accéder à un champ non aligné au mot machine.
    Vouloir gérer toi-même l'alignement rendra de plus ton code au mieux non-portable, au pire lentissime partout.

    J'ai fais l'expérience une fois, avec des milliers de petites structures packées de travers.
    Pour une réduction de 2% de la mémoire, j'ai pris triplé le temps d'exécution.

    Un pc dispose de Milliards d'octets de mémoire. C'est énorme devant le padding.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut Même élément d'une structure mais size différents ?
    Quand j'ai dit géré de la mémoire indépendamment, c'est aussi avec un système d'adressage qui m'est propre et de façon moins complexe afin d'accéder plus rapidement à une des zones mémoire disponible. Plus clairement, j'ai une structure qui représente l'adresse postale d'une donnée (emplacement etc.), et la seconde le type de donnée à cet emplacement.
    Je suis conscient que mon application ne peut être portable a cause des raisons d'économies de mémoire mais, le but est d'avoir un programme de gestion de mémoire indépendant du système actuel même si la zone mémoire réservée est fournie par le système.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/08/2011, 17h43
  2. permutation des éléments d'une structure
    Par nadsky dans le forum Débuter
    Réponses: 2
    Dernier message: 27/11/2008, 13h31
  3. Pointeur sur les éléments d'une structure
    Par Marley_T dans le forum C
    Réponses: 16
    Dernier message: 05/05/2008, 23h31
  4. Accès aux éléments d'une structure
    Par licorne dans le forum Pascal
    Réponses: 1
    Dernier message: 15/02/2007, 17h44
  5. push_back avec un élément d'une structure
    Par Chewbi dans le forum C++
    Réponses: 5
    Dernier message: 08/04/2006, 14h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo