对于某些结构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
为什么?
答案 0 :(得分:5)
这不仅仅是关于变量的顺序。你永远不会使用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
局部变量)。
e.g。
int bar (void)
{
struct foo a;
struct foo b;
/* Do some work. */
}
这里,a
和b
在我的机器编译器上用8个字节分隔,即使每个foo
只使用5个字节。
所有这些都表明:从不在编写代码时假设与宽度,对齐,相对位置等有关的任何内容。
答案 1 :(得分:2)
编译器可以自由地重新排序堆栈上变量的位置,因此b
变量可能位于s1
指针之前,尽管后者是在中间声明的。 / p>
由于某些数据类型需要对齐,这种重新排列可能会提高内存利用率,从而消除任何可能的差距。
答案 2 :(得分:1)
你是说因为指针s1
是在a
和b
之间分配的,地址需要根据指针使用内存的数量而变化吗? (我不太清楚)。
如果是这样,我认为你不能指望这一点,如何在不同变量之间分配内存不受你的控制。可能看起来内存是以线性方式分配的,但它不是你可以依赖的东西。
如果我错误地解释了您的问题/请您重新说明/澄清一下吗?