繁体   English   中英

了解C中的地址

[英]Understanding addresses in C

对于某些结构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 ,编译器可以(也可以 )简单地优化它,而不是在堆栈上分配空间。

如果我尝试仅打印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局部变量)。

例如

int bar (void)
{
  struct foo a;
  struct foo b;

  /* Do some work.  */
}

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

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

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

由于某些数据类型需要对齐,因此这种重新排列可以实现更好的存储器利用,从而消除任何可能的间隙。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM