Order of elements in stucts and classes

I just found out, that depending on how you place elements in structures and classes they can have different size, for example:

1
2
3
4
5
6
7
8
9
10
11
struct things1 {
	char ch;
	int a;
	double x;
}; // 16 bytes

struct things2 {
	char ch;
	double x;
	int a;
}; // 24 bytes, 1.5 times larger! 

So my question is how should I place elements in my types, so that they use only as much memory as they need. Should I place the biggest types at the beginning, like so:
1
2
3
4
5
struct things3 {
	double x;
	int a;
	char ch;
};
Last edited on
How did you find this out? Do you have a proof?
You might want to place elements to minimise padding. doubles for example should be 8-byte aligned, so they could only be placed at memory address which is divisible by 8. Any extra memory between end of previous member and first viable address is unused (padding)
By learning about aligment and structure padding you might be able to select optimal order for your data.

Another way to remove padding is to explicitely state so. How it is done differs between compilers, and access to unaligned data is really slow, so you might kill perfomance by doing that.
Last edited on
@IWishIKnew I used sizeof operator

I know how it works and what it is, but what I don't know is how to "place elements to minimise padding".
If I'd like to place short, int, long, double and float in stuct then how should I place them efficiently?
Like so?
1
2
3
4
5
6
7
struct blab{
    double a;
    long b; // long, float and int can be in any 
    float c;// order, as they are all 4 bytes
    int d;
    short e;
};
1
2
    long b; // long, float and int can be in any 
    float c;// order, as they are all 4 bytes[ 
Wrong. long is 8 bytes on 64bit Linux. int is 2 bytes on 16 bit architectures and 8 bytes on some strict 64 bit architectures. Standard does not require them to be of some specific size. It just places some constraints.

So in general it is impossible to do that portable. If you want to do it for specific platform, you should read on type sizes and aligment restrictions for that specific platform and compiler
I have 64-bit Windows 8 so at least at my system they are the same size. And even if it cannot be portable it can be helpful in creating systems. But my question is still the same. Is this good order? Maybe nobody knows, 'cuz nobody thought of it earielr(I doubt it).
If it works for you, use it.
Again, it seems to work:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct things1 {
	double a;
	long b;
	float c;
	int d;
	short e;
}; // 24 bytes

struct things2 {
	short e;
	double a;
	long b;
	float c;
	int d;
}; // 32 bytes 

But I still don't know if there is any better way or not. Thanks for your replay MiiNiPaa! I'll leave that post for a while unresolved, maybe sb knows the exact answear. If not I'll close it.
Last edited on
What do you mean by "better way"?

Anyway, this article is really good to understand how padding works and why compiler works that way:
http://www.catb.org/esr/structure-packing/
By better way I mean a way to save even more memory with basically nothing. Thank you for that link, I'll read it tomorrow. It's late in my country, and in yours it's even 2 hours later.
You cannot use less memory than sum of all data sizes rounded up to nearest value divisible by maximum aligment of data. That means things1 cannot use less than 24 bytes.
I've not read that post you gave me entirely yet, but after half of it I can already say that's what I was looking for. Thank You! My questions are solved!
Topic archived. No new replies allowed.