2011-12-01 2 views
0

Possible en double:
Why isn't sizeof for a struct equal to the sum of sizeof of each member?
Extra bytes when declaring a member of a struct as uint32_tTaille de l'opérateur renvoie une taille incorrecte?

Pour une raison quelconque, l'opérateur sizeof retourne une taille bogus pour cette structure (48 au lieu de 40):

typedef struct mbdb_file_info { 
    uint16_t mode; 

    uint32_t unk0; 
    uint32_t unk1; 
    uint32_t user_id; 
    uint32_t group_id; 

    uint32_t time0; 
    uint32_t time1; 
    uint32_t time2; 

    uint64_t length; 
    uint8_t flag; 
    uint8_t property_count; 
} mbdb_file_info; 

Voici donc un test simple:

printf("%ld %ld %ld %ld: %ld", sizeof(uint8_t), 
           sizeof(uint16_t), 
           sizeof(uint32_t), 
           sizeof(uint64_t), 
           sizeof(mbdb_file_info)); 

qui imprime:

1 2 4 8: 48

Comment cela se produit? Si vous ajoutez toutes les tailles ensemble, vous obtenez 40, pas 48. D'où vient le 48?

Et si c'est un peu bizarre x86-64 perk, comment puis-je m'assurer que tous les champs des structures occupent les montants que je veux qu'ils occupent (je lance un tas d'octets à cette structure)?

Répondre

3

Le compilateur peut ajouter des octets au milieu de la structure afin d'aligner les membres de la structure. La taille de la structure est au moins la somme de la taille des membres, mais ne s'y limite pas.

+0

Oh, alors j'ai besoin de 'struct volatile '? –

+0

Vous devez ajouter '__attribute __ ((packed))'. –

+4

@S'il vous plaît noter qu'il est possible que l'utilisation de 'packed' * peut affecter les performances de votre programme. Un accès mémoire non aligné peut être plus coûteux qu'un accès aligné et peut faire une différence mesurable dans une boucle. –

0

Alignement. Certains types de données sont alignés sur certaines limites (lues: adresses divisibles par un facteur de 2, par exemple 16), en fonction de l'architecture, ce qui provoque un bourrage dans la structure.

Il existe des options du compilateur pour supprimer ce comportement, and the gcc documentation tells you how to use the aligned attribute pour cela.

0

Ceci est appelé rembourrage de structure pour l'alignement. Ce qui est susceptible de se produire est que les valeurs 8 et 16 bits sont complétées à 32 bits et que la structure entière est complétée pour être un multiple de la taille du mot machine (8).

1

En raison du rembourrage de la structure (pas sûr quel était le terme ici). Le plus grand champ est 64bit, donc tout est aligné selon lui. Ainsi, nous avons:

typedef struct mbdb_file_info { 
    uint16_t mode; // 16 + 

    uint32_t unk0; // 32 = 48, so add 16 more to align to 64bit; 
    uint32_t unk1; // this 
    uint32_t user_id; // and this give 64bits ; 
    uint32_t group_id; // again this 

    uint32_t time0; // plus this - 64bits; 
    uint32_t time1; // this 
    uint32_t time2; // and this = 64bit ; 

    uint64_t length; // this is 64 by itself 
    uint8_t flag; // this 
    uint8_t property_count; // +this is 16, add 48 for the alignment 
} mbdb_file_info; // when you sum all bits (+ the additional for padding) 
         // you have exactly 48B 
3

Vous pouvez également vous débarrasser du rembourrage en réorganisant vos membres struct. Par exemple, si vous déclarez le 64 bits, puis 32, puis 16, puis 8, il sera naturellement aligné et ne pas avoir des octets de remplissage supplémentaires.

Questions connexes