I am trying to understand the size of a struct based on it's members as described a brief tutorial on data alignment (see here. The article states that "All data is naturally aligned within the structure. If type
is located at address 0 the following double x
is located with an offset of 8 at address 8 and so on. As a consequence the size of this structure is 48 even though it contains only 37 bytes of meaningful data. And yes, if float m
follows directly after type
the offset of m will be four and the size of the structure reduced to 40." The sentence
And yes, if float m follows directly after type the offset of m will be four and the size of the structure reduced to 40.
does not make sense to me. Why would the struct size be reduced to 40 just because the order of the members is changed? Is it because double vy
is offset by 40 bytes and then an additional 8 bytes are padded resulting in a struct size of 48? While if float m
follows directly after type
, the offset of double vy
is only 32 bytes, and then an additional 8 bytes are added resulting in a struct size of 40?
I have written a small C program to double check the alignments of the struct members:
/*Outputs:
particle one alignment:
type 0
x 8
y 16
m 24
vx 32
vy 40
struct size --> 48
particle two alignment:
type 0
m 4
x 8
y 16
vx 24
vy 32
struct size --> 40
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct ParticleOne {
char type;
double x,y;
float m; // after `y` member
double vx, vy;
} ParticleOne;
typedef struct ParticleTwo {
char type;
float m; // after `type` member
double x,y;
double vx, vy;
} ParticleTwo;
int main() {
ParticleOne *particle_one = malloc(sizeof(ParticleOne));
ParticleTwo *particle_two = malloc(sizeof(ParticleTwo));
// Particle one alignment/offset information
void *p1_type = &particle_one->type;
void *p1_x = (void*)&particle_one->x - p1_type;
void *p1_y = (void*)&particle_one->y - p1_type;
void *p1_m = (void*)&particle_one->m - p1_type;
void *p1_vx = (void*)&particle_one->vx - p1_type;
void *p1_vy = (void*)&particle_one->vy - p1_type;
printf("particle one alignment:\n");
printf("type %d\n", p1_type - p1_type);
printf("x %d\n", p1_x);
printf("y %d\n", p1_y);
printf("m %d\n", p1_m);
printf("vx %d\n", p1_vx);
printf("vy %d\n", p1_vy);
printf("struct size --> %d\n", sizeof(ParticleOne));
// Particle two alignment/offset information
void *p2_type = &particle_two->type;
void *p2_x = (void*)&particle_two->x - p2_type;
void *p2_y = (void*)&particle_two->y - p2_type;
void *p2_m = (void*)&particle_two->m - p2_type;
void *p2_vx = (void*)&particle_two->vx - p2_type;
void *p2_vy = (void*)&particle_two->vy - p2_type;
printf("particle two alignment:\n");
printf("type %d\n", p2_type - p2_type);
printf("m %d\n", p2_m);
printf("x %d\n", p2_x);
printf("y %d\n", p2_y);
printf("vx %d\n", p2_vx);
printf("vy %d\n", p2_vy);
printf("struct size --> %d\n", sizeof(ParticleTwo));
return 0;
}