填充C中的结构

let*_*tsc 40 c structure padding

这是一个面试问题.直到现在,我曾经认为这些问题纯粹依赖于编译器,不应该担心我,但现在,我对它很好奇.

假设您有两种结构:

struct A {  
  int* a;  
  char b;  
 }  
Run Code Online (Sandbox Code Playgroud)

而且,

struct B {  
  char a;  
  int* b;  
}  
Run Code Online (Sandbox Code Playgroud)

那么你更喜欢哪一个?为什么?我的回答是这样的(虽然我有点在黑暗中拍摄)第一个结构应该是首选的,因为编译器为字大小的一些倍数(这是指针的大小 - 在32上的4个字节)分配结构的空间位机和64位的8字节).因此,对于这两种结构,编译器将分配8个字节(假设它是32位机器).但是,在第一种情况下,填充将在所有变量之后(即在a和b之后)完成.因此,即使有一些机会,b得到一些溢出的值并破坏我的下一个填充字节,但我的a仍然是安全的.

他似乎并不高兴,并要求第一个结构在第二个结构上的一个缺点.我没有太多话要说.:d

请帮我解答.

MBy*_*ByD 34

我不认为任何这种结构都有优势.这个等式中有一个(!)常数.结构成员的顺序保证是声明的.

所以如下所示,第二个结构可能有一个优势,因为它可能有一个较小的尺寸,但在你的例子中,因为它们可能具有相同的大小:

struct {
    char a;
    int b;
    char c;
} X;
Run Code Online (Sandbox Code Playgroud)

比.

struct {
    char a;
    char b;
    int c;
} Y;
Run Code Online (Sandbox Code Playgroud)

关于以下评论的更多解释:

以下所有不是100%,但结构将在32位系统中构造的常见方式,其中int为32位:

结构X:

|     |     |     |     |     |     |     |     |     |     |     |     |
 char  pad    pad   pad   ---------int---------- char   pad   pad   pad   = 12 bytes
Run Code Online (Sandbox Code Playgroud)

结构Y:

|     |     |     |     |     |     |     |     |
 char  char  pad   pad   ---------int----------        = 8 bytes
Run Code Online (Sandbox Code Playgroud)

  • @MByD:他的第二个可能同样大,因为最后会有填充,这样当数组中有两个或更多个时,成员仍然会在其自然边界上对齐,而不仅仅是第一个. (2认同)

cni*_*tar 11

当值与某些边界对齐时,某些机器可以更有效地访问数据.有些需要对齐数据.

在现有的32位机器上,如SPARC或英特尔[34] 86,或任何来自68020的摩托罗拉芯片,每个数据通常必须是"自我对齐",从一个地址开始,它的地址是它的倍数类型大小.因此,32位类型必须从32位边界开始,16位边界上的16位类型,8位类型可以从任何地方开始,struct/array/union类型具有其最严格的成员的对齐.

所以你可以拥有

struct B {  
    char a;
    /* 3 bytes of padding ? More ? */
    int* b;
}
Run Code Online (Sandbox Code Playgroud)

在"自对齐"情况下最小化填充(并且在大多数其他情况下没有损害)的简单规则是通过减小大小来命令结构成员.

我个人认为第一个结构与第二个结构相比并不缺点.