2009-12-03 21 views
35

Eventuali duplicati:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?dimensione di struct in C

consideri il seguente codice C:

#include <stdio.h>  

struct employee 
{ 
    int id; 
    char name[30]; 
}; 

int main() 
{ 
    struct employee e1;  
    printf("%d %d %d", sizeof(e1.id), sizeof(e1.name), sizeof(e1)); 
    return(0); 
} 

Il risultato è:

Perché la dimensione della struttura non è uguale alla somma delle dimensioni delle sue singole variabili componente?

+1

È possibile utilizzare l'attributo confezionato in gcc. Ciò eliminerà il riempimento e manterrà la struttura il più piccola possibile. struct test_t { int c; } __attribute __ ((__ packed__)); – eaanon01

+0

Duplicato di (almeno) http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – dmckee

+6

eaanon01 . non dovresti dire a nessuno di qualcosa di non vendibile come attributo confezionato a meno che non ci sia una ragione veramente buona e tutte le implicazioni siano comprese. –

risposta

52

Il compilatore può aggiungere il riempimento per i requisiti di allineamento. Nota che questo non si applica solo al padding tra i campi di una struct, ma può anche applicarsi alla fine della struct (in modo che gli array del tipo di struttura abbiano allineato ogni elemento).

Ad esempio:

struct foo_t { 
    int x; 
    char c; 
}; 

anche se il campo c non ha bisogno di imbottitura, la struct avrà generalmente un sizeof(struct foo_t) == 8 (su un sistema a 32 bit - piuttosto un sistema con un 32-bit di tipo int) perché ci devono essere 3 byte di padding dopo il campo c.

Si noti che il padding potrebbe non essere richiesto dal sistema (come x86 o Cortex M3) ma i compilatori potrebbero ancora aggiungerlo per motivi di prestazioni.

+1

+1, sebbene l'allineamento a 6 byte suoni strani. Forse sono un po 'indietro nelle cose di basso livello, però. –

+1

Bene, il nome inizia con l'offset 4 (abbastanza plausibile) e si estende fino a 34. 34 non è un multiplo di 4 quindi è completato a 36, ​​che è 9 * 4. Ha senso per me! –

+2

Allineamento ai limiti 32bit (4,8,16,24,32,36, ...) – Mordachai

0

Allineamento a 6 byte non è strano, perché si sta allineando agli indirizzi più a 4.

Quindi, in pratica si dispone di 34 byte nella struttura e la struttura successiva dovrebbe essere immessi sul indirizzo, che è multiplo per 4. Il valore più vicino dopo 34 è 36. E questa area di riempimento conta nella dimensione della struttura.

2

Come accennato, il compilatore C aggiungerà il riempimento per i requisiti di allineamento. Questi requisiti hanno spesso a che fare con il sottosistema di memoria. Alcuni tipi di computer possono accedere solo alla memoria allineata ad un valore "bello", come 4 byte. Questo è spesso uguale alla lunghezza della parola. Pertanto, il compilatore C può allineare i campi della struttura a questo valore per renderli più facili da accedere (ad esempio, i valori di 4 byte devono essere allineati a 4 byte) Inoltre, può eseguire il rilievo della parte inferiore della struttura per allineare i dati che seguono la struttura . Credo che ci siano anche altri motivi. Maggiori informazioni possono essere trovate alla pagina di wikipedia this.

1

L'allineamento predefinito è probabilmente 4 byte. O l'elemento da 30 byte ha 32, oppure la struttura nel suo insieme è stata arrotondata al successivo intervallo di 4 byte.