【问题标题】:Size of with paddding带填充的大小
【发布时间】:2018-03-16 20:17:24
【问题描述】:

以下结构在 32 位机器上的大小(以字节为单位)是多少 安装Linux操作系统?

sizeof(int) = 4 字节
sizeof(short) = 2 字节
sizeof(char) = 1 字节

1

struct foo {
    int d1;
    char c1;
    int d2;
}

2

struct foo {
    int d1;
    char c1;
    int d2;
    char c2;
    short s;
};

3

struct foo{
    int d1;
    int d2;
    char c1;
    char c2;
    short s;
};

4

struct foo {
    char c1;
    int d1;
    short s;
    int d2;
    char c2;
};

答案:
12,
16,
12,
20

有人能解释一下如何找到这些答案吗?我很困惑,不理解这里的概念。

有人可以解释每个的填充要求吗?这就是我的困惑。我不明白需要什么。 !

【问题讨论】:

  • 我很确定这是一个常见的副本。

标签: c struct


【解决方案1】:

它与数据类型的对齐有关,这意味着特定的数据类型(例如 int)可能不会从任何地址开始,而是在 - 比如说 - 仅在内存地址 p % 4 == 0 上开始。这允许编译器(取决于架构)利用处理器通常为此类数据类型提供的优化。

似乎int 的对齐方式为4,即它可能仅从内存地址p % 4 == 0 开始。因此,如果您有一个带有int d1,然后是char c1,然后是int d2 的结构,编译器需要在c1 之后引入3 个填充字节,以便d2 从地址p % 4 == 0 开始。这就是为什么。

没有(或限制较少)对齐限制的数据类型可以在没有(或更少)填充之间进行打包。

接下来的事情是这样的struct“继承”对齐限制,因为这样的对象本身必须从一个地址开始,这样它的成员的对齐限制才不会被违反。这意味着如果你有一个结构体,其ints 和对齐4,如果连续对象违反对齐方式,这样的结构体对象本身可能有尾随填充字节。请注意,(普通)数组保证数组元素之间没有填充,因此任何填充都必须是结构的一部分。这适用于您的示例 4,因此大小为 20(而不是 17)。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    对于 32 位 x86 机器,这些值是正确的:

    sizeof(int) = 4 bytes
    sizeof(short) = 2 bytes
    sizeof(char) = 1 byte
    

    以下是 64 位 Linux 机器的值:

    /*
       EXAMPLE OUTPUT (64-bit Linux):
         sizeof(char)=     1
         sizeof(int)=      4
         sizeof(short)=    2
         sizeof(long)=     8
         sizeof(long long)=8
         sizeof(char *)   =8
     */
    #include <stdio.h>
    
    int main (int argc, char *argv[]) {
      printf ("sizeof(char)=%d  \n", (int)sizeof (char));
      printf ("sizeof(int)=%d  \n", (int)sizeof (int));
      printf ("sizeof(short)=%d  \n", (int)sizeof (short));
      printf ("sizeof(long)=%d  \n", (int)sizeof (long));
      printf ("sizeof(long long)=%d  \n", (int)sizeof (long long));
      printf ("sizeof(char *)=%d  \n", (int)sizeof (char *));
      return 0;
    }
    

    然而,“填充”取决于实现:

    https://wiki.sei.cmu.edu/confluence/display/c/EXP03-C.+Do+not+assume+the+size+of+a+structure+is+the+sum+of+the+sizes+of+its+members

    C 标准的子条款 6.7.2.1 指出,“可能有未命名的 在结构对象内填充,但不在其开头” [ISO/IEC 9899:2011]。

    不同的编译器可以以不同的方式“填充”结构中的元素。

    填充的一个令人信服的原因是“性能”。例如:

    https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/

    如果整数分配在不是 4 的倍数的地址,它 跨越两排银行,如下图所示。这样的 一个整数需要两个内存读取周期来获取数据。

    变量的数据对齐处理数据存储的方式 这些银行。例如 int 在 32 位上的自然对齐 机器是 4 个字节。当数据类型自然对齐时,CPU 以最短的读取周期获取它。

    同样,short int 的自然对齐方式是 2 个字节...

    因此,在您的示例中,字段 d1、c1 和 d2 的偏移量为:

    offset(foo.d1)=0
    offset(foo.c1)=4  <-- This is true for 32-bit or 64-bit x86/x64 CPUs
    offset(foo.d2)=8  <-- So is this...
    

    总大小为 4 + 4 + 4 = 12

    【讨论】:

      猜你喜欢
      • 2014-04-29
      • 2017-03-16
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 2018-12-18
      • 2011-05-07
      • 1970-01-01
      相关资源
      最近更新 更多