对此没有规定。这取决于您使用的实现。此外,它可能会根据编译器选项而改变。您可以做的最好的事情是打印每个变量的地址。然后就可以看到内存布局是怎样的了。
类似这样的:
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;
}
可能的输出:
num: 0x7ffee97fce84 - size 4
s : 0x7ffee97fce83 - size 1
ptr: 0x7ffee97fce88 - size 8
另外请注意,如果您不获取变量的地址 (&),编译器可能会优化您的代码,以便该变量根本不会放入内存中。
一般而言,对齐通常是为了从所使用的硬件平台中获得最佳性能。这通常意味着变量与其大小对齐,或者对于大小大于 4 的变量,至少对齐 4 个字节。
更新:
OP 在更新中给出了一个特定的布局示例,并询问该布局是否可以/将会发生。
同样的答案是:依赖于实现
所以原则上它可能发生在某些特定系统上。也就是说,我怀疑它会在任何主流系统上发生。
还有一个用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;
}
我系统的输出:
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
请注意内存中的位置与代码中定义的顺序变量有何不同。这确保了良好的对齐。
按地址排序:
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
所以再次回答更新问题:
在大多数系统上,我怀疑你会看到一个 4 字节的变量被放置在地址 xxx2、xxx6 或 xxxa、xxxe。但是,系统可能存在于可能发生这种情况的地方。