Original Post
I was curious about C structures and how they were laid out in memory. I wrote the following programming to give show me a few things about structures. The output is: I compiled this Apple's gcc 4.0.1 without any options. Obviously the memory is 4-byte aligned. Is memory alignment something that can be depended on, or is it something so horrific between vendors/compilers/operating systems that you should never make any assumptions on it? If I made assumptions on memory alignment, I would have to ensure that all binaries (such as loadable libraries) were compiled right. Seems pretty scary to me - but there are some definite optimizations that could be made. I'm just curious to hear from anyone who have already felt this out.
#include <stdlib.h>
#include <stdio.h>
int type_banana = 1;
int type_orange = 2;
int type_apple = 3;
struct object {
int type;
char* size;
};
typedef struct object object;
struct banana {
int type;
char* size;
float softness;
int length;
};
typedef struct banana banana;
struct orange {
int type;
char* size;
unsigned char peeled;
};
typedef struct orange orange;
struct apple {
int type;
char* size;
short weight;
char* color;
};
typedef struct apple apple;
banana* make_banana(char* size, float softness, int length) {
banana* b = (banana*)malloc(sizeof(banana));
b->type = type_banana;
b->size = size;
b->softness = softness;
b->length = length;
return b;
}
orange* make_orange(char* size, unsigned char peeled) {
orange* o = (orange*)malloc(sizeof(orange));
o->type = type_orange;
o->size = size;
o->peeled = peeled;
return o;
}
apple* make_apple(char* size, float weight, char* color) {
apple* a = (apple*)malloc(sizeof(apple));
a->type = type_apple;
a->size = size;
a->weight = weight;
a->color = color;
return a;
}
int main(int argc, char** argv) {
apple* a = make_apple("small", 2.5, "red");
banana* b = make_banana("big", 1.5, 5);
object* generic1 = (object*)a;
object* generic2 = (object*)b;
printf("generic1 size: %s\n", a->size);
printf("generic2 size: %s\n", b->size);
printf("\nLocations:\n");
printf("apple: 0x%x\n", a);
printf("apple->type: 0x%x\n", &a->type);
printf("apple->size: 0x%x\n", &a->size);
printf("apple->weight: 0x%x\n", &a->weight);
printf("apple->color: 0x%x\n", &a->color);
printf("\nSizes:\n");
printf("apple: %d\n", sizeof(apple));
printf("apple->type: %d\n", (long)&a->size - (long)&a->type);
printf("apple->size: %d\n", (long)&a->weight - (long)&a->size);
printf("apple->weight: %d\n", (long)&a->color - (long)&a->weight);
printf("apple->color: %d\n", ((long)a + sizeof(apple)) - (long)&a->color);
}
generic1 size: small
generic2 size: big
Locations:
apple: 0x100120
apple->type: 0x100120
apple->size: 0x100124
apple->weight: 0x100128
apple->color: 0x10012c
Sizes:
apple: 16
apple->type: 4
apple->size: 4
apple->weight: 4
apple->color: 4