我把你的程序改写成了一个只会转储内存的东西。这应该能更好地让你了解内存中的布局。
正如其他人指出的那样,编译器不能保证内存布局。即使检查内存地址,也可能会改变编译器组织内存的方式。你的问题不是关于C语言,而是关于你特定编译器的怪癖。
#include <stdio.h>
#include <string.h>
int main()
{
char a_arr[16] = "";
char *a = a_arr;
char b_arr[1] = "";
char *b = b_arr;
void *min, *max, *curr;
min = &a_arr;
if (min > (void *)&a) {
min = &a;
}
if (min > (void *)&b_arr) {
min = &b_arr;
}
if (min > (void *)&b) {
min = &b;
}
max = (void *)&a_arr + sizeof(a_arr);
if (max < (void *)&a + sizeof(a)) {
max = (void *)&a + sizeof(a);
}
if (max < (void *)&b_arr + sizeof(b_arr)) {
max = (void *)&b_arr + sizeof(b_arr);
}
if (max < (void *)&b + sizeof(b)) {
max = (void *)&b + sizeof(b);
}
for (curr = min; curr <= max; ++curr) {
if (curr == &a_arr)
printf ("%10p: %10x - a_arr\n", curr, *((char *)curr));
else if (curr == &a)
printf ("%10p: %10x - a\n", curr, *((char *)curr));
else if (curr == &b_arr)
printf ("%10p: %10x - b_arr\n", curr, *((char *)curr));
else if (curr == &b)
printf ("%10p: %10x - b\n", curr, *((char *)curr));
else
printf ("%10p: %10x\n", curr, *((char *)curr));
}
printf ("\nThe amount by which they differ is: %d\n", a-b);
return 0;
}
这是在我的机器上运行的情况。请注意,b_arr后面有三个浪费的字节。这些字节被用来使每个变量从4的倍数地址开始(这称为字边界对齐,非常标准)。
我怀疑你的编译器正在将b_arr对齐到16字节边界。这很不寻常但也不奇怪。编译器为了速度而做出最奇怪的事情。
这里还有一个问题
(这里),很好地说明了内存对齐的不可预测性。总的来说,您不应该将内存布局视为确定性。
ffbfefbc: ffffffff - b
ffbfefbd: ffffffbf
ffbfefbe: ffffffef
ffbfefbf: ffffffc0
ffbfefc0: 0 - b_arr
ffbfefc1: 0
ffbfefc2: 0
ffbfefc3: 0
ffbfefc4: ffffffff - a
ffbfefc5: ffffffbf
ffbfefc6: ffffffef
ffbfefc7: ffffffc8
ffbfefc8: 0 - a_arr
ffbfefc9: 0
ffbfefca: 0
ffbfefcb: 0
ffbfefcc: 0
ffbfefcd: 0
ffbfefce: 0
ffbfefcf: 0
ffbfefd0: 0
ffbfefd1: 0
ffbfefd2: 0
ffbfefd3: 0
ffbfefd4: 0
ffbfefd5: 0
ffbfefd6: 0
ffbfefd7: 0
ffbfefd8: 0
The amount by which they differ is: 8