c++ c struct sizeof memory-alignment

c++ - ¿Por qué el tamaño de esta estructura es 24?



sizeof memory-alignment (3)

4 4 2 8 2 2 - se empacarán como:

4 4 4 8 2 2 - los dos últimos se combinan en 4 bytes. el tercer elemento necesita relleno, el último y el último no.

Tengo una estructura de la cual quiero calcular su tamaño:

#pragma pack(push,4) struct MyStruct { uint32_t i1; /* size=4, offset=0. */ uint32_t i2; /* size =4 offset =4 */ uint16_t s1; /* size =2 offset=8 */ unsigned char c[8]; /* size=8 offset=12*/ uint16_t s2; /* size=2 offset=20. */ uint16_t s3; /* size=2 offset=24. */ } ; // total size is 26 static_assert(sizeof(MyStruct) == 24, "size of MyStruct incorrect"); #pragma pack(pop)

La afirmación estática muestra que el tamaño es 24, pero mi cálculo muestra que debería ser 26.

¿Por qué es el tamaño 24?

Estoy trabajando en Windows 7, aplicación de 32 bits usando Visual Studio 2012


La alineación de uint16_t es solo 2, por lo tanto, los desplazamientos son:

#pragma pack(push,4) struct MyStruct { uint32_t i1; /* offset=0 size=4 */ uint32_t i2; /* offset=4 size=4 */ uint16_t s1; /* offset=8 size=2 */ unsigned char c[8]; /* offset=10 size=8 */ uint16_t s2; /* offset=18 size=2 */ uint16_t s3; /* offset=20 size=2 */ /* offset=22 padding=2 (needed to align MyStruct) */ } ; // total size is 24

Editar El relleno al final es necesario para garantizar que todos los elementos de

MyStruct A[10]; // or MyStruct*B = new MyStruct[10];

están alineados apropiadamente. Esto requiere que sizeof(MyStruct) sea ​​un múltiplo de alignof(MyStruct) . Aquí, sizeof(MyStruct) = 6 * alignof(MyStruct) .

Cualquier tipo de struct / class siempre se rellena al siguiente múltiplo de su alineación.


Además de la respuesta de Walter, considera atrapar este pez tú mismo. Todo lo que necesita es la función printf y la aritmética simple:

struct MyStruct ms; printf("sizeof(ms): %zd/n", sizeof(ms)); printf("i1/t%td/n", (uint8_t*)&ms.i1 - (uint8_t*)&ms); printf("i2/t%td/n", (uint8_t*)&ms.i2 - (uint8_t*)&ms); printf("s1/t%td/n", (uint8_t*)&ms.s1 - (uint8_t*)&ms); printf("c /t%td/n", (uint8_t*)&ms.c - (uint8_t*)&ms); printf("s2/t%td/n", (uint8_t*)&ms.s2 - (uint8_t*)&ms); printf("s3/t%td/n", (uint8_t*)&ms.s3 - (uint8_t*)&ms);

( %zd es para imprimir size_t , %td para imprimir ptrdiff_t . Un simple %d probablemente funcionará bien en la mayoría de los sistemas).

Salida:

sizeof(ms): 24 i1 0 i2 4 s1 8 c 10 s2 18 s3 20