2009-12-03 76 views
35

Duplicar posibles:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?tamaño de struct en C

Consideremos el siguiente código 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); 
} 

La salida es:

¿Por qué el tamaño de la estructura no es igual a la suma de los tamaños de sus variables de componentes individuales?

+1

Puede usar el atributo empaquetado en gcc .. Esto soltará el relleno y mantendrá la estructura lo más pequeña posible. struct test_t { int c; } __tribuir __ ((__ empaque__)); – eaanon01

+0

Duplicado de (al menos) http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – dmckee

+6

eaanon01 . no debe decirle a nadie sobre algo tan poco importante como el atributo empaquetado a menos que haya una razón realmente buena y se entiendan todas las implicaciones. –

Respuesta

52

El compilador puede agregar relleno para los requisitos de alineación. Tenga en cuenta que esto se aplica no solo al relleno entre los campos de una estructura, sino que también puede aplicarse al final de la estructura (de modo que las matrices del tipo de estructura tendrán cada elemento alineado correctamente).

Por ejemplo:

struct foo_t { 
    int x; 
    char c; 
}; 

A pesar de que el campo c no necesita relleno, la estructura tendrá generalmente un (en un sistema de 32 bits sizeof(struct foo_t) == 8 - en lugar de un sistema con un tipo de 32 bits int) porque habrá que tener 3 bytes de relleno después del campo c.

Tenga en cuenta que es posible que el sistema no requiera el relleno (como x86 o Cortex M3), pero los compiladores aún pueden agregarlo por motivos de rendimiento.

+1

+1, aunque alinear a 6 bytes suena raro. Sin embargo, tal vez estoy un poco atrasado en cosas de bajo nivel. –

+1

Bueno, el nombre comienza en el desplazamiento 4 (lo suficientemente plausible) y se extiende a 34. 34 no es un múltiplo de 4, por lo que es acolchado a 36, ​​que es 9 * 4. ¡Tiene sentido para mi! –

+2

Su alineación a los límites de 32 bits (4,8,16,24,32,36, ...) – Mordachai

0

Alinear a 6 bytes no es raro, ya que se está alineando a varias direcciones a 4.

Así que, básicamente, que tiene 34 bytes en su estructura y la siguiente estructura debe ser colocado en la dirección, es decir a múltiples 4. El valor más cercano después de 34 es 36. Y este área de relleno cuenta en el tamaño de la estructura.

2

Como se mencionó, el compilador de C agregará relleno para los requisitos de alineación. Estos requisitos a menudo tienen que ver con el subsistema de memoria. Algunos tipos de computadoras solo pueden acceder a la memoria alineada con algún valor 'bueno', como 4 bytes. Esto a menudo es lo mismo que la longitud de la palabra. Por lo tanto, el compilador de C puede alinear los campos de su estructura con este valor para facilitar el acceso (por ejemplo, los valores de 4 bytes deben estar alineados en 4 bytes). Además, puede rellenar la parte inferior de la estructura para alinear los datos que siguen a la estructura . Creo que hay otras razones también. Más información se puede encontrar en this página wikipedia.

1

Su alineación predeterminada es probablemente de 4 bytes. O el elemento de 30 bytes obtuvo 32, o la estructura como un todo se redondeó al siguiente intervalo de 4 bytes.