2 votes

Pourquoi le court est stocké comme 4 octets dans un struct en C ?

J'ai les deux structs suivants :

Le problème est que sizeof(Content) renvoie 160. La structure est composée de 11 shorts, 6 ints, 76 chars, 7 floats, 1 double, soit un total de 158 octets. J'ai compté trois fois et il y a toujours une différence de 2 octets.

typedef struct TIME_T { 
    short year,mon,day; 
    short hour,min,sec; 
} TIME;

typedef struct { 
    int no; 
    char name[20]; 
    char Code[10]; 
    char DASType[10]; 
    short wlen; 
    float VLtd; 
    int samp; 
    int comp; 
    int locationID; 
    short TranMode; 
    char TranIns[12]; 
    short TimerMode; 
    char ClkType[12]; 
    float ClkErr; 
    float lat; 
    float lon; 
    float alt; 
    float azimuth,incident; 
    short weight; 
    short veloc; 
    int oritype; 
    char seismometer[12]; 
    double sens; 
    TIME start_time; 
    int record_samples; 
} Content;

J'écris un petit bout de code pour imprimer la position de chaque variable dans la structure, et soudain je trouve la float wlen prend 4 octets. Mon code est le suivant :

int main(void)
{   
    Content content;
    printf("Sizeof Content: %d\n", sizeof(content));
    printf("Sizeof int content.no: %d\n", (int)&content.name - (int)&content.no);
    printf("Sizeof char[20] content.name: %d\n", (int)&content.Code - (int)&content.name);
    printf("Sizeof char[10] content.Code: %d\n", (int)&content.DASType - (int)&content.Code);
    printf("Sizeof char[10] content.DASType: %d\n", (int)&content.wlen - (int)&content.DASType);
    printf("Sizeof short content.wlen:  %d\n", (int)&content.VLtd - (int)&content.wlen);
    printf("Sizeof float content.VLtdL %d\n", (int)&content.samp - (int)&content.VLtd);
    printf("Sizeof int content.samp: %d\n", (int)&content.comp - (int)&content.samp);
    printf("Sizeof int content.comp: %d\n", (int)&content.locationID - (int)&content.comp);
    printf("Sizeof int content.locationID: %d\n", (int)&content.TranMode - (int)&content.locationID);
    printf("Sizeof short content.TranMode: %d\n", (int)&content.TranIns - (int)&content.TranMode);
    printf("Sizeof char[12] content.TranIns: %d\n", (int)&content.TimerMode - (int)&content.TranIns);
    printf("Sizeof short content.TimerMode: %d\n", (int)&content.ClkType - (int)&content.TimerMode);
    printf("Sizeof char[12] content.ClkType: %d\n", (int)&content.ClkErr - (int)&content.ClkType);
    printf("Sizeof float content.ClkErr: %d\n", (int)&content.lat - (int)&content.ClkErr);
    printf("Sizeof float content.lat: %d\n", (int)&content.lon - (int)&content.lat);
    printf("Sizeof floatcontent.lon: %d\n", (int)&content.alt - (int)&content.lon);
    printf("Sizeof floatcontent.alt: %d\n", (int)&content.azimuth - (int)&content.alt);
    printf("Sizeof floatcontent.azimuth: %d\n", (int)&content.incident - (int)&content.azimuth);
    printf("Sizeof floatcontent.incident: %d\n", (int)&content.weight - (int)&content.incident);
    printf("Sizeof short content.weight: %d\n", (int)&content.veloc - (int)&content.weight);
    printf("Sizeof short content.veloc: %d\n", (int)&content.oritype - (int)&content.veloc);
    printf("Sizeof int content.oritype: %d\n", (int)&content.seismometer - (int)&content.oritype);
    printf("Sizeof char[12] content.seismometer: %d\n", (int)&content.sens - (int)&content.seismometer);
    printf("Sizeof double content.sens: %d\n", (int)&content.start_time - (int)&content.sens);
    printf("Sizeof TIME content.start_time: %d\n", (int)&content.record_samples - (int)&content.start_time);
    printf("Sizeof int content.record_samples: %d\n", sizeof(content.record_samples));

    getchar();
    return 0;
}

Le résultat est le suivant :

Sizeof int content.no: 4
Sizeof char[20] content.name: 20
Sizeof char[10] content.Code: 10
Sizeof char[10] content.DASType: 10
Sizeof short content.wlen:  4
**Sizeof float content.VLtdL 4**
Sizeof int content.samp: 4
Sizeof int content.comp: 4
Sizeof int content.locationID: 4
Sizeof short content.TranMode: 2
Sizeof char[12] content.TranIns: 12
Sizeof short content.TimerMode: 2
Sizeof char[12] content.ClkType: 12
Sizeof float content.ClkErr: 4
Sizeof float content.lat: 4
Sizeof floatcontent.lon: 4
Sizeof floatcontent.alt: 4
Sizeof floatcontent.azimuth: 4
Sizeof floatcontent.incident: 4
Sizeof short content.weight: 2
Sizeof short content.veloc: 2
Sizeof int content.oritype: 4
Sizeof char[12] content.seismometer: 12
Sizeof double content.sens: 8
Sizeof TIME content.start_time: 12
Sizeof int content.record_samples: 4

Le compilateur est MSVC8, pas d'UNICODE défini, pas d'autre macro définie. C'est x86.

J'ai essayé de compiler le même code dans gcc version 3.4.4, la sortie est la même. Sizeof short content.wlen: 4

Quelqu'un peut-il m'expliquer cela ?

Merci d'avance.

EDIT : Merci d'avoir répondu ! J'ai compris maintenant.

23voto

dfa Points 54490

Réponse courte seulement : alignement

11voto

Vous ne pouvez pas calculer la taille d'une structure en additionnant simplement les tailles de tous ses composants - le compilateur est autorisé à insérer des espaces entre les champs, ce qu'il fait fréquemment.

4voto

PaulJWilliams Points 11641

Alignement - sur une architecture 32 bits, il est beaucoup plus efficace de faire circuler la mémoire par morceaux de 32 bits. Vous n'économiseriez en fait aucune mémoire en stockant un court-circuit sur 16 bits, car il ferait toujours partie d'un mot associé de 32 bits.

3voto

Brian Rasmussen Points 68853

Vous ne calculez pas la taille des champs, mais la "distance" entre eux, donc je suppose que ce que vous voyez est l'alignement des mots dans la structure.

3voto

Kevin Montrose Points 11936

L'ajout d'un autre court-circuit à la structure augmente-t-il la taille ou la maintient-il inchangée ? Je parie qu'il reste de la même taille.

Les deux compilateurs s'efforcent de garder votre structure alignée sur 8 octets (je suppose), donc un champ va être "étendu" pour occuper l'espace supplémentaire ; les opérations réelles sur ce champ se comporteront comme s'il avait la taille "correcte".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X