【问题标题】:Size of the structure assuming that padding is enabled假设启用了填充的结构的大小
【发布时间】:2017-03-05 02:34:01
【问题描述】:

假设我有一个定义如下所示的结构:

 typedef struct
 {
   char a;
   int b;
   char c;
 }abc_t;

现在根据填充规则,字符变量可以从任何地址开始,因为它只有一个字节,而整数变量应该从可以被 4 整除的地址开始,而短变量应该从任何偶数地址开始。 在这种情况下,如果我们假设字符变量从 OFFSET 0 开始。

struct
{
    char a; // OFFSET 0+3 bytes padding
    int b;  // OFFSET 4
    char c; //OFFSET 5+3 bytes padding
}abc_t;

这里结构的总大小将变为 12。

但我的疑问是,如果结构的第一个元素是 'char a' 这里从偏移量 1 开始,那么根据填充规则,我们只会在 a 之后填充 2 个字节,因此结构的大小将是 8 个字节。

struct
{
    char a;//OFFSET 1+2 bytes
    int b;//OFFSET 4
    char c;//OFFSET 8
}abc_t;

任何以短变量开头的结构变量也是如此。 您能否告诉我我对此的理解是否正确,或者我们是否可以安全地假设任何结构的第一个成员总是从可被 4 整除的地址开始?

非常感谢。

【问题讨论】:

  • 在合理常见的限制/假设下,显示的结构将以 4 个字节的倍数开始。结构中不能有前导填充。其他结构可能需要或多或少地严格对齐。例如,struct ver1 { char a; short b; char c; } 的大小可能为 6,并在任何偶数边界上对齐,而struct ver2 { char a; double d; char e; } 的大小可能为 24,并在 8 字节的任意倍数上对齐。
  • 我很确定有一个规则,结构的第一个成员的地址在数字上总是等于结构的地址,即在第一个成员之前没有任何填充,即第一个成员的偏移量始终为 0。
  • @SteveSummit:绝对:§6.7.2.1 结构和联合说明符 ¶15 ...结构对象中可能有未命名的填充,但不是在其开头。 …¶17 结构或联合的末尾可能有未命名的填充。

标签: c padding


【解决方案1】:

这里有几个问题:

1) int 的大小不需要 4 个字节,它的 sizeof(int) 是编译器定义的。可以是 4 字节、8 字节甚至 2 字节,具体取决于字长。见Is the size of C "int" 2 bytes or 4 bytes?。

2) 结构中的字段对齐由编译器决定。您放置字段的顺序并不能保证更紧密的包装。但是,字段的顺序被保留。见Why isn't sizeof for a struct equal to the sum of sizeof of each member?。

3) 将较短的结构放在一起通常会导致更紧密的打包。

4) 结构从单词边界开始。第一个字段之前永远没有任何填充。所以是的,地址将在单词的开头。 Why use address of first element of struct, rather than struct itself?.

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2021-07-23
    • 2016-09-18
    • 2020-07-26
    • 2012-08-22
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多