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

标签 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 Data2adress开始(Data1) + 4 而不是 char Data1[1]

并且,按照相同的逻辑,为什么我在 short Data2 之后没有 short Padding3[1]

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

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 */
};

那么总大小 24 字节是 8 字节的倍数?

最佳答案

结构的整体对齐应该是具有最大对齐要求的元素的对齐。例如,这是为了确保结构数组始终对齐的目的所必需的。如果没有,则 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;
};

关于c++ - 内存对齐结构 - 对齐大小等于最大成员大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26246576/

相关文章:

C++11 及更高版本 : shared_ptr for managing system resources provided by a low-level C library

c - 如何使用 scanf 获取我想要的字符串?

c - 指针内存错误

c - 标准 C 预处理器如何解释 "0xFFFFFFFF"?

c++ - "natural_alignment_of"类型特征?

c++ - OpenCV:查找轮廓(); - 我使用的是什么内核

c++ - strcat_s 添加奇怪的字符

c++ - 获取 cv::Mat 的源 ROI 坐标

c++ - C++ 中未对齐访问的正确性

c++ - 它叫 "memory alignment"还是 "data alignment"?