Hvorfor kort lagres som 4 byte i en struct i C?

stemmer
2

Jeg har følgende to structs:

Problemet er sizeof (Content) returnerer 160. struct består av 11 shorts, 6 ints, 76 tegn, 7 flyter, en dobbel, helt legger til 158 bytes. Jeg har regnet tre ganger, og det er fortsatt to byte forskjell.

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;

Jeg skriver et lite stykke kode for å skrive ut plasseringen av hver variabler i struct, og plutselig finner jeg float wlentar 4 byte. Koden min er som følger:

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;
}

Utgangen er som følger:

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

Kompilatoren er MSVC8, ingen UNICODE definert, ingen andre makro definert. Det er x86.

Jeg prøvde å kompilere den samme koden i gcc versjon 3.4.4, produksjonen er den samme. Sizeof short content.wlen: 4

Kan noen forklare dette for meg?

Takk på forhånd.

EDIT: Takk for svar! Jeg har fått det nå.

Publisert på 07/05/2009 klokken 08:47
kilden bruker
På andre språk...                            


9 svar

stemmer
23

korte svaret bare: justering

Svarte 07/05/2009 kl. 08:50
kilden bruker

stemmer
11

Du kan ikke trene på størrelse med en struct ved å legge størrelsen på alle komponentene - kompilatoren er lov til å sette polstring mellom feltene, og ofte gjør.

Svarte 07/05/2009 kl. 08:51
kilden bruker

stemmer
4

Alignment - på en 32 bits arkitektur, er det mye mer effektivt å passere minnet rundt i 32 bit biter. Du ville ikke faktisk spare noe minne i det hele tatt ved å lagre et kort på 16 bits, så det vil fortsatt være en del av en tilhørende 32 bits ord.

Svarte 07/05/2009 kl. 08:53
kilden bruker

stemmer
3

Strukturmedlemmer er ofte innrettet på 4-byte grenser hvis kompilatoren finner at tilgangen vil være mer praktisk på den måten. Lignende skjer med røye.

Du kan prøve å optimalisere minne fotavtrykk av strukturen ved å sette shorts sammen, slik at to påfølgende shorts bruke en enkelt 32-bits ord. Ikke glem å dobbeltsjekke kompilatoren resultater.

Svarte 07/05/2009 kl. 09:00
kilden bruker

stemmer
3

Har legger til et annet kort til strukturen utvide størrelsen, eller holde den samme? Min innsats er det forblir samme størrelse.

Begge kompilatorer arbeider for å holde på linje strukturen 8-byte (jeg antar), så noen felt kommer til å bli "utvidet" til å ta opp ekstra plass; faktiske operasjoner på det feltet vil oppføre seg som om det var "riktig" størrelse.

Svarte 07/05/2009 kl. 08:53
kilden bruker

stemmer
3

Du er ikke å beregne størrelsen på feltene, men "avstand" mellom dem, så jeg antar det du ser er ordinnrettingen i struct.

Svarte 07/05/2009 kl. 08:53
kilden bruker

stemmer
2

Som dfa sa, er det grunn til justering. En "god praksis" som kan bidra til å redusere størrelsen på strukturene er å bestille den er medlem av deres individuelle størrelse (faktisk deres individuelle justering, men størrelsen er ofte godt nok) og starter med det største medlemmet.

Dette er ikke alltid sant, men mesteparten av tiden.

Svarte 07/05/2009 kl. 09:31
kilden bruker

stemmer
2

Ifølge C standard, har hver innfødte type i minnet for justert av sin størrelse, men er ikke direkte relatert til problemet ditt. Hva du bør se nærmere på er struct pakking.

Svarte 07/05/2009 kl. 09:06
kilden bruker

stemmer
1

Ta en titt på pahole, forkortelse for Poke-a-Hole. Det er en av de DWARF2 verktøy som brukes til å finne hull i structs, hull være mellomrom mellom medlemmer på grunn av justeringsregler, som kan brukes til nye struct oppføringer eller omorganiseres for å redusere størrelsen.

Les mer om det i denne LWN artikkel av forfatteren av programmet, Arnaldo Carvalho de Melo.

Det er ikke mange opplæringsprogrammer for å bli funnet på nettet, men denne wikien-siden ved CERN er noe nyttig.

Svarte 07/05/2009 kl. 09:08
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more