对于一些结构splab
:
int main() {
int a;
struct splab *s1;
int b;
printf("%x\n",&a);
printf("%x\n",&b);
return 0;
}
我想我应该在第二个打印中得到:bfc251e8 - 8
(即考虑到 s1
占用的空间)。
相反,我得到了:
bfc251e8
bfc251ec
为什么?
最佳答案
这不仅仅是关于变量的顺序。您从不使用 s1
,编译器可以(并且可能)简单地优化它而不在堆栈上分配空间。
如果我像您一样尝试只打印 a
和 b
的地址,我会得到以下结果:
ffeb7448 (&a)
ffeb7444 (&b)
即相差 4 个字节。
如果我也尝试打印 s1
的地址(因此最终使用声明 s1
),我会得到以下结果:
ffe109cc (&a)
ffe109c8 (&s1)
ffe109c4 (&b)
你可以看到这次它确实位于 a
和 b
之间(并不总是如此,正如其他答案已经指出的那样),并且a
和 b
由 8 个字节而不是 4 个字节分隔。
另一个稍微相关的点与对齐有关:
例如:
struct foo
{
int a;
char b;
};
虽然这个结构在具有 4 字节整数的机器上看起来可能是 5 字节宽,但我的编译器说,sizeof (struct foo) == 8
。
这样一来,foo
始终对齐 8 字节边界(这包括使用 struct foo
局部变量)。
例如
int bar (void)
{
struct foo a;
struct foo b;
/* Do some work. */
}
这里,a
和 b
在我机器的编译器上被 8 个字节分隔,尽管每个 foo
实际上只使用 5 个字节。
所有这一切表明:永远不要在编写代码时假定任何与宽度、对齐方式、相对位置等相关的内容。
关于c - 了解 C 中的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11292729/