First of all, never assume the padding in a struct. It works fairly reliably, but is technically undefined behavior.
And much more importantly, you are breaking the strict aliasing rule. This is an assumption by the compiler that you never access the same memory location with pointers of different types (in this case, struct first*
and char*
). You can get around this with the -fno-strict-aliasing
or use unions to do type-punning, as it's usually called. Go here for more info.
The more correct version of this code will be -
#include <stdio.h>
#include <stdlib.h>
#include <alloca.h>
#include <string.h>
struct first {
int a;
int b;
};
struct second {
int c;
int d;
struct first * f_t[2];
};
int main()
{
struct second *p;
char a[24] = {1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0};
p = alloca(sizeof(struct second));
memset(p, 0, sizeof(struct second));
memcpy(p, a, sizeof(int)*2);
p->f_t[0]= alloca(sizeof(struct first));
p->f_t[1]= alloca(sizeof(struct first));
memset(p->f_t[1], 0, sizeof(struct first));
memset(p->f_t[0], 0, sizeof(struct first));
memcpy(p->f_t[0], a + 8, sizeof(struct first));
memcpy(p->f_t[1], a + 16, sizeof(struct first));
printf("%d %d %d %d %d %d",p->c,p->d,p->f_t[0]->a,p->f_t[0]->b,p->f_t[1]->a,p->f_t[1]->b);
}
NOTE: Using alloca()
is bad practice. Don't use it unless you know what you're doing. It's fine here since it's simply one small struct being allocated on the stack, but in general steer away from it and use malloc()
or just use local variables.
This still technically falls under undefined behavior, since we're assuming how the structs are padded, which is implementation specific, but most platforms use self aligned data types and are a lot faster when using properly aligned structures, so it's easy to guess. For more information on this, go here. I still strongly discourage this as this is undefined behavior, and it's very easy to mess up.
Also, the next time onward, make sure to provide a minimal, complete and compilable example.