了解C中的地址

时间:2012-07-02 11:27:24

标签: c pointers

对于某些结构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

为什么?

3 个答案:

答案 0 :(得分:5)

这不仅仅是关于变量的顺序。你永远不会使用s1,编译器可以(和可能)简单地优化它,而不是在堆栈上分配空间。

如果我尝试仅打印ab的地址,我会得到以下内容:

ffeb7448 (&a)
ffeb7444 (&b)

即。 4个字节的差异。

如果我尝试打印s1的地址(因此最终使用声明s1),我会得到以下内容:

ffe109cc (&a)
ffe109c8 (&s1)
ffe109c4 (&b)

您可以看到它确实位于ab之间(并且它并不总是,正如其他答案已经指出的那样),以及ab由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.  */
}

这里,ab在我的机器编译器上用8个字节分隔,即使每个foo只使用5个字节。

所有这些都表明:从不在编写代码时假设与宽度,对齐,相对位置等有关的任何内容。

答案 1 :(得分:2)

编译器可以自由地重新排序堆栈上变量的位置,因此b变量可能位于s1指针之前,尽管后者是在中间声明的。 / p>

由于某些数据类型需要对齐,这种重新排列可能会提高内存利用率,从而消除任何可能的差距。

答案 2 :(得分:1)

你是说因为指针s1是在ab之间分配的,地址需要根据指针使用内存的数量而变化吗? (我不太清楚)。

如果是这样,我认为你不能指望这一点,如何在不同变量之间分配内存不受你的控制。可能看起来内存是以线性方式分配的,但它不是你可以依赖的东西。

如果我错误地解释了您的问题/请您重新说明/澄清一下吗?