There are no rules for this. It depends on the implementation you are using. Further it may change depending on compiler options. The best you can do is to print the address of each variable. Then you can see how the memory layout is.
Something like this:
int main(void)
{
int num;
char s;
int *ptr;
printf("num: %p - size %zu\n", (void*)&num, sizeof num);
printf("s : %p - size %zu\n", (void*)&s, sizeof s);
printf("ptr: %p - size %zu\n", (void*)&ptr, sizeof ptr);
return 0;
}
Possible output:
num: 0x7ffee97fce84 - size 4
s : 0x7ffee97fce83 - size 1
ptr: 0x7ffee97fce88 - size 8
Also notice that in case you don't take the address (&
) of a variable, the compiler may optimize your code so that the variable is never put into memory at all.
In general the alignment is typically made to get the best performance out of the HW platform used. That typically imply that variables are aligned to their size or at least 4 byte aligned for variables with size greater than 4.
Update:
OP gives a specific layout example in the update and asks if that layout can/will ever happen.
Again the answer is: It is implementation dependent
So in principle it could happen on some specific system. That said I doubt that it will happen on any mainstream system.
There is another code example compiled with gcc -O3
int main(void)
{
short s1;
int i1;
char c1;
int i2;
char c2;
printf("s1: %p - size %zu\n", (void*)&s1, sizeof s1);
printf("i1: %p - size %zu\n", (void*)&i1, sizeof i1);
printf("c1: %p - size %zu\n", (void*)&c1, sizeof c1);
printf("i2: %p - size %zu\n", (void*)&i2, sizeof i2);
printf("c2: %p - size %zu\n", (void*)&c2, sizeof c2);
return 0;
}
Output from my system:
s1: 0x7ffd222fc146 - size 2 <-- 2 byte aligned
i1: 0x7ffd222fc148 - size 4 <-- 4 byte aligned
c1: 0x7ffd222fc144 - size 1
i2: 0x7ffd222fc14c - size 4 <-- 4 byte aligned
c2: 0x7ffd222fc145 - size 1
Notice how the location in memory differs from the order variables was defined in the code. That ensures a good alignment.
Sorting by address:
c1: 0x7ffd222fc144 - size 1
c2: 0x7ffd222fc145 - size 1
s1: 0x7ffd222fc146 - size 2 <-- 2 byte aligned
i1: 0x7ffd222fc148 - size 4 <-- 4 byte aligned
i2: 0x7ffd222fc14c - size 4 <-- 4 byte aligned
So again to answer the update-question:
On most systems I doubt you'll see a 4 byte variable being placed at address xxx2, xxx6 or xxxa, xxxe. But still, systems may exist where that could happen.