2012-10-02 12 views
6

È una domanda semplice. Codice primaC++ sizeof with bool

struct A { 
    int x; 
}; 
struct B { 
    bool y; 
}; 
struct C { 
    int x; 
    bool y; 
}; 

In funzione principale, mi chiamano

cout << " bool : " << sizeof(bool) << 
    "\n int : " << sizeof(int) << 
    "\n class A : " << sizeof(A) << 
    "\n class B : " << sizeof(B) << 
    "\n class C : " << sizeof(C) << "\n"; 

e il risultato è

bool : 1 
int : 4 
class A : 4 
class B : 1 
class C : 8 

Perché le dimensioni di classe C 8 invece di 5? Nota che questo è stato compilato con gcc in MINGW 4.7/Windows 7/32 bit.

+0

che si chiama imbottitura. – Marlon

+0

@Marlon quindi, qual è lo scopo principale del padding? – Sungmin

+0

@Sungmin: pensa agli array. –

risposta

6

L'allineamento di un aggregato è quella del suo stretto membro (l'elemento con il più grande requisito di allineamento). In altre parole, la dimensione della struttura è un multiplo dell'allineamento del suo membro più severo (con il requisito di allineamento più grande).

struct D 
{ 
    bool a; 
    // will be padded with char[7] 
    double b; // the largest alignment requirement (8 bytes in my environment) 
}; 

La dimensione della struttura di cui sopra sarà di 16 byte perché 16 è un multiplo di 8. Nel tuo esempio il tipo stretto è int allineamento a 4 byte. Ecco perché la struttura è riempita per avere 8 byte. Vi darò un altro esempio:

struct E 
{ 
    int a; 
    // padded with char[4] 
    double b; 
}; 

La dimensione della struttura di cui sopra è 16. 16 è multiplo di 8 (allineamento del doppio nel mio ambiente).

ho scritto un post sul blog su allineamento di memoria per una spiegazione più dettagliata http://evpo.wordpress.com/2014/01/25/memory-alignment-of-structures-and-classes-in-c-2/

+0

Non è il tipo più lungo; è l'allineamento del tipo il cui allineamento è "più severo" (vale a dire il più lungo). In molti ABI, i double sono lunghi 8 byte ma solo a 4 byte allineati, per esempio. (In teoria, dovrebbe essere il LCM di tutti gli allineamenti, ma lo standard richiede che "Ogni valore di allineamento deve essere un potere integrale non negativo di due" (3.11, paragrafo 4), quindi puoi semplicemente prendere quello più lungo.) – rici

2

Allineare le strutture alle dimensioni di una parola, che è 4 byte qui.

+0

Posso chiedere ulteriormente? Qual è la ragione della struttura di allineamento? – Sungmin

+0

Questo non spiega la strategia di allineamento o può essere la risposta non è completa. Se è allineato a 4, anche la struct B sarebbe di 4 byte. Tuttavia, la sua dimensione è 1 byte. Inoltre nella mia risposta ho dimostrato che il compilatore è allineato a 8 byte che non è ancora 4. Il mio punto è che allinea la dimensione della struttura a un multiplo del tipo più grande che contiene. Questo lo spiega meglio. – evpo

-1

Osservando la definizione della propria struct, si ha un valore di 1 byte seguito da un intero di 4 byte. Questo numero intero deve essere allocato su un limite di 4 byte, che costringerà il compilatore a inserire un padding di 3 byte dopo il bool da 1 byte. Che rende la dimensione della struct a 8 byte. Per evitare ciò, è possibile modificare l'ordine degli elementi nella struttura.

Anche per due dimensioni di chiamate che restituiscono valori diversi, sei sicuro di non avere un errore di battitura qui e non stai prendendo la dimensione del puntatore o di un tipo diverso o di qualche variabile intera.

risposto con Rohit J sul struct size is different from typedef version?

+0

Nel mio caso, la modifica dell'ordine degli elementi nella struct C non ha influenzato il risultato. – Sungmin

+0

@Sungmin: l'ordine dei membri di solito non influisce sul riempimento. Considera che se 'int' deve essere allineato a un limite di 4 byte, può essere ordinato come' bool', padding, 'int'; o 'int',' bool', riempimento. Si noti che in un array, ogni elemento è localizzato 'sizeof (type)' byte oltre il precedente. –

+0

@Sungmin: hai ragione. In questo caso la modifica dell'ordine non cambierebbe la dimensione della 'struct'. –