2012-10-02 32 views
6

Es una pregunta simple. Código primero.C++ sizeof con bool

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

En función principal, que llaman

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

y el resultado es

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

¿Por qué es el tamaño de la clase C 8 en lugar de 5? Tenga en cuenta que esto se compila con gcc en la máquina MINGW 4.7/Windows 7/32 bit.

+0

que se llama relleno. – Marlon

+0

@Marlon Entonces, ¿cuál es el objetivo principal del relleno? – Sungmin

+0

@Sungmin: piense en las matrices. –

Respuesta

6

La alineación de un agregado es el de su miembro más estricto (el miembro con el mayor requisito de alineación). En otras palabras, el tamaño de la estructura es un múltiplo de la alineación de su miembro más estricto (con el mayor requisito de alineación).

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

El tamaño de la estructura anterior será de 16 bytes porque 16 es un múltiplo de 8. En su ejemplo del tipo más estricto es int alinear a 4 bytes. Es por eso que la estructura está acolchada para tener 8 bytes. Te voy a dar otro ejemplo:

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

El tamaño de la estructura anterior es 16. 16 es múltiplo de 8 (alineación de doble en mi entorno).

escribí un post sobre la alineación de memoria para una explicación más detallada http://evpo.wordpress.com/2014/01/25/memory-alignment-of-structures-and-classes-in-c-2/

+0

No es el tipo más largo; es la alineación del tipo cuya alineación es "más estricta" (es decir, más larga). En muchos ABI, los dobles son de 8 bytes de longitud, pero solo 4 bytes alineados, por ejemplo. (Teóricamente, debería ser el MCM de todas las alineaciones, pero el estándar requiere que "cada valor de alineación sea una potencia integral no negativa de dos" (3.11, párrafo 4), por lo que puede tomar la más larga). – rici

2

Alineación de estructuras con el tamaño de una palabra, que es de 4 bytes aquí.

+0

¿Puedo solicitar más? ¿Cuál es el motivo de la estructura de alineación? – Sungmin

+0

Esto no explica la estrategia de alineación o puede ser que la respuesta no sea completa. Si se alinea con 4, entonces struct B tendría 4 bytes también. Sin embargo, su tamaño es de 1 byte. También en mi respuesta demostré que el compilador estaba alineado con 8 bytes, que no es 4 nuevamente. Mi punto es que alinea el tamaño de la estructura con un múltiplo del tipo más grande que contiene. Eso lo explica mejor. – evpo

-1

Al observar la definición de su estructura, tiene un valor de 1 byte seguido de un entero de 4 bytes. Este entero debe asignarse en un límite de 4 bytes, lo que obligará al compilador a insertar un relleno de 3 bytes después de su bool de 1 byte. Lo que hace que el tamaño de struct sea de 8 bytes. Para evitar esto, puede cambiar el orden de los elementos en la estructura.

También para dos llamadas sizeof que devuelven valores diferentes, ¿está seguro de que no tiene un error tipográfico aquí y no está tomando el tamaño del puntero o el tipo diferente o una variable entera?

Respondido por Rohit J en struct size is different from typedef version?

+0

En mi caso, cambiar el orden de los elementos en la estructura C no influyó en el resultado. – Sungmin

+0

@Sungmin: el orden de los miembros no suele afectar al relleno. Considere que si el 'int' debe estar alineado con un límite de 4 bytes, puede ordenarse como' bool', relleno, 'int'; o 'int',' bool', relleno. Tenga en cuenta que en una matriz, cada elemento se encuentra 'sizeof (tipo)' bytes más allá de la anterior. –

+0

@Sungmin: estás en lo cierto. En este caso, cambiar el orden no cambiaría el tamaño de la 'struct'. –