¡Pasen! ¡Pasen y vean! Se trata de un problema que es recursivo en mi vida, viene de vez en cuando para darme dolores de cabeza hasta que recuerdo que esto me pasó hace ya unos años, otra vez :P.
Para que no se me vuelva a olvidar:
#include<stdio.h> struct structMadness { int a; char b; }; int main() { struct structMadness sm; printf("sizeof(int)=%d\n", sizeof(int)); printf("sizeof(char)=%d\n", sizeof(char)); printf("sizeof(sm)=%d\n", sizeof(sm)); return 0; }
Un programa sencillo, ¿no? Tenemos una estructura con un entero y un caracter, y mostramos por pantalla el tamaño de un entero, un caracter y de la estructura.
$ gcc main.c -o main $ ./main sizeof(int)=4 sizeof(char)=1 sizeof(sm)=8
¡Ahí está! El tamaño de a (4 bytes) más el tamaño de b (1 byte), suma... ¡8 bytes!
Pruébenlo en casa, no muerde.
Resulta que el compilador, al reservar memoria para la estructura, está alineándola a 32 bits (en mi caso el int son 32 bits, el char son 8 bits, así que añade 24 bits más para ser múltiplo de 32). Esto podemos comprobarlo con un gcc -S main.c para ver el código ensamblador que genera, donde se aprecia un align 4 (en mi caso, GCC 2.95.4).
Bueno, esto es así y hay que convivir con ello. Cualquier compilador nos permitirá compactar la estructura de forma que no haya alineamiento (bueno, sí lo hay... pero es al byte, lo cual no nos causará problemas).
Cambiamos la estructura por:
struct structMadness { int a; char b; } __attribute__ ((packed));
Ahora repetimos la ejecución:
$ ./main sizeof(int)=4 sizeof(char)=1 sizeof(sm)=5
Bien, esto ya es más razonable ;).
¿Dónde puede ser esto un problema? Cuando leemos una estructura de disco. Si se grabó compactada, hay que leerla compactada, sino el alineamiento nos hará leer de más (o de menos si leemos compactando una estructura que se grabó sin compactar :D).
Además podría darse un caso en el que el alineamiento no fuera siempre de 32 bits, con los que datos guardados/leídos con alineamientos diferentes llevarían a error al recuperar los datos guardados.
Espero que no se me vuelva a olvidar.

![[xml]](/images/xml.gif)
