内存对齐到结构 - 对齐大小等于最大成员大小

时间:2014-10-07 22:53:34

标签: c++ c memory-alignment

我想知道为什么我们必须对于结构的对齐大小,将对齐大小等于最大成员大小的结构。

示例:

struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
}; 

如果我们采用最大的成员(int Data3),对齐是4个字节,所以我们必须这样做:

struct MixedData  /* After compilation in 32-bit x86 machine */
{
    char Data1; /* 1 byte */
    char Padding1[1]; /* 1 byte for the following 'short' to be aligned on a 2 byte boundary 
                         assuming that the address where structure begins is an even number */
    short Data2; /* 2 bytes */
    int Data3;  /* 4 bytes - largest structure member */
    char Data4; /* 1 byte */
    char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */
};

但为什么我不能在char Data1 char Padding1[3] short Data2之后adress(Data1) + 4开始char Data1[1]而不是short Padding3[1]

而且,基于同样的逻辑,为什么short Data2之后我不能struct MixedData /* After compilation in 64-bit x86_64 machine */ { char Data1; /* 1 byte */ char Padding1[7]; /* 7 bytes */ int Data3; int Padding2[1]/* 4 bytes */ char Data4; char Padding3[7]; /* 7 bytes to make total size of the structure 24 bytes */ };

另一个问题:如果我使用64位处理器,我应该使用8字节对齐,所以我要设置以下内容:

{{1}}

所以24字节的总大小是8字节的倍数?

1 个答案:

答案 0 :(得分:0)

结构的总体对齐应该是具有最大对齐要求的元素的对齐。这是为了确保例如结构阵列始终对齐所必需的。如果您没有,struct { int x; char c; };的大小将使第一个元素对齐,但接下来的三个元素将x未对齐。

通常可以说服编译器生成“打包”数据结构(没有对齐填充)并使用它来获取打包数组,但在所有但非常特殊的情况下使用它是个坏主意,因为充其量它更慢,最坏的情况是由于处理器中的“未对齐访问陷阱”导致执行停止。

如果int的大小是四个字节[它适用于我所知道的所有编译器 - long是4或8个字节,取决于编译器],两者都在32-和64位(至少x86)将是4字节对齐。

如果你想在结构中有一个7字节的“间隙”,这将有效:

struct X { 
   char c;
   uint64_t x;
}; 

当然会有:

struct X { 
   char c;
   char padding[7]; 
   uint64_t x;
};