【问题标题】:C programming : padding in structureC编程:结构中的填充
【发布时间】:2018-02-19 06:30:47
【问题描述】:

我正在使用

processor architecture: x86_64
OS                    : Debian GNU/Linux 9 (stretch) 64-bit
GCC compiler ver.     : 6.3.0

如果我编译这段代码 -

struct test {char a; int b;}
test;
printf("%ld", sizeof(test);

然后输出是 - 8 我假设它是因为 4 个字节填充,我的意思是 1+3+4 现在我尝试了这段代码-

struct test{char a; double b;} 
test;

这给了我 16 个字节,然后我想,可能是因为 8 个字节的填充,即 - 现在我尝试这段代码时是 1+7+8 -

struct test{char a; long double b; char c;}
test;

这给了我 48 个字节

在我使用 gcc 的系统中,int = 4 byte,double = 8 byte,char = 1 byte,long double = 16 byte。

我的问题是这是如何工作的?为什么不是统一的填充?

【问题讨论】:

  • “对齐”是您应该研究的关键字。
  • 这一行 printf("%ld", sizeof(test); 缺少括号。请发布显示问题的Minimal, Complete, and Verifiable example。无论如何应该是printf("%zu", sizeof(test));

标签: c memory padding


【解决方案1】:

你用你的第三个结构改变了模式。如果你有第三种结构,你会得到与前两种模式一致的数字:

struct A { char a; int b; };         // 1 +  3 +  4 =  8
struct B { char a; double b; };      // 1 +  7 +  8 = 16
struct C { char a; long double b; }; // 1 + 15 + 16 = 32

现在,当您在 long double 之后放置另一个 char 时,您只需要多一个字节,但编译器会添加另外 15 个字节的填充:

struct D { char a; long double b; char c; }; // 1 + 15 + 16 + 1 + 15?!

我认为您真正想问的问题是,它为什么要这样做?它这样做是因为数组。 C 标准说,数组元素之间永远不能有任何填充。但是为了使内部填充能够保持b 正确对齐到 16 个字节,struct D 本身必须对齐到 16 个字节。如果 struct D 的长度为 33 个字节,则数组 struct D dee[2] 的第二个元素将未对齐。所以编译器必须在struct Dend 插入更多的填充,使其大小成为对齐的倍数。

【讨论】:

  • 您说 - “保持 b 正确对齐到 16 个字节”,但编译器可以将其对齐到 8 个字节,而不是这样做。所以 b 将有两个部分。因为我有 64 位 cpu,它会一次使用 16*8 位数据(b 的内容)做什么?这可以节省内存而不是 16 字节对齐。
  • 现在我们说“64 位 CPU”是指它的 指针 是 64 位宽。这并不意味着它对大于 64 位的对齐没有用处。碰巧的是,在 x86-64 上,long double 是 128 位宽,ABI 也要求与 128 位对齐;该文档没有说明 为什么 它提出了这个要求,但我猜想要么数据总线至少 128 位宽,要么作者想保留它在未来。
猜你喜欢
  • 2023-04-03
  • 2015-04-25
  • 1970-01-01
  • 2014-10-12
  • 2011-10-21
  • 1970-01-01
  • 2020-11-27
  • 2021-07-23
  • 1970-01-01
相关资源
最近更新 更多