c - 了解 C 中的地址

标签 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

为什么?

最佳答案

这不仅仅是关于变量的顺序。您从不使用 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 个字节。

所有这一切表明:永远不要在编写代码时假定任何与宽度、对齐方式、相对位置等相关的内容。

关于c - 了解 C 中的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11292729/

相关文章:

c++ - 如何在交叉编译期间强制链接到未安装的库

c++ - 对 "av_new_packet"的 undefined reference (使用 Qt)

c - 如何轻松地对 C 代码进行基准测试?

c - 结构数组指针

c - 为什么编译器可以接受这个?

C 如果每次都跳过一个

我可以在同一个程序中编写服务器、客户端代码并运行它们吗

c - 在 C 中,当头指针位置未知时,在单个链表中插入节点

c - 如何用指针在c中添加相邻的数组项?

c++ - 如何理解复杂的数组声明指针,以及 &