struct something {
uint32_t a;
uint8_t b;
uint16_t c;
uint32_t x;
uint16_t y;
uint8_t z;
};
uint8_t *data = malloc(14);
struct something *s = (struct something *)data;
s->a = 1;
s->b = 2;
s->c = 3;
s->x = 4;
s->y = 5;
s->z = 6;
Is it always safe to do this in C or structure padding may cause problems?
Edit 1 (make it clear): is it guaranteed that data[0]..data[3]==1, data[4]==2, data[5]..data[6]==3, data[7]..data[10]==4, data[11]..data[12]==5 and data[13]==6?
Edit 2: little mistake on edit 1
This is not a safe operation. The compiler will add padding in an implementation defined manner.
Generally speaking, a member of a given size will be aligned on an offset that is a multiple of that size.
Given the typical way padding is done, this struct will most likely be 16 bytes in size. The physical layout will most likely (but not necessarily) look like this:
struct something {
uint32_t a; // offset 0
uint8_t b; // offset 4
// 1 byte padding
uint16_t c; // offset 6
uint32_t x; // offset 8
uint16_t y; // offset 12
uint8_t z; // offset 14
// 1 byte padding
};
Don't use magic numbers. Intead, use the sizeof operator.
struct something *s = malloc(sizeof(struct something));
EDIT:
If you want to increase the chances that your struct is laid out a particular way, see this guide to structure packing. If you follow the practices here, there's a good chance (but not 100%) that your struct will be laid out in memory the way you expect.
For gcc, you can use __attribute__((packed)) on a struct to remove padding from a struct. Doing so however may incur a performance penalty or could cause a page fault. The -Wpadded and -Wpacked options can also tell you more regarding padding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With