类对齐问题

时间:2015-01-29 07:36:50

标签: c++ memory-alignment

我正在测试一个类对齐并发现了奇怪的行为。我使用VS2012编译器设置48字节对齐设置对其进行了测试,但在每种情况下输出都相同。

class Alignemnt{
public:
    Alignemnt():a(){}
    int a;
};

class Alignemnt_1{
public:
    int a;
    char array[2];
};

class Alignemnt_2{
public:
    int a;
    char array[2];
    int x;
};

std::cout <<  "Sizeof(Alignemnt)   :" <<sizeof(Alignemnt) << std::endl;
std::cout <<  "Sizeof(Alignemnt_1) :" <<sizeof(Alignemnt_1) << std::endl;
std::cout <<  "Sizeof(Alignemnt_2) :" <<sizeof(Alignemnt_2) << std::endl;

每次输出都是:

Sizeof(Alignemnt)   : 4

Sizeof(Alignemnt_1) : 8

Sizeof(Alignemnt_2) : 12

我认为,Alignemnt_2大小应为16字节。

3 个答案:

答案 0 :(得分:2)

我假设您指的是/Zp开关,它允许您控制最大结构成员对齐:

  

当您指定此选项时,第一个之后的每个结构成员都存储在成员类型的大小或n字节边界(其中n是1,2,4,8或16)中,以较小者为准。

由于您没有使用对齐超过4个字节的结构成员(sizeof(int)alignof(int)都是4),所有4个字节及以上的设置将导致完全相同的行为

如果要指定结构成员的完全对齐方式,请考虑使用标准C ++ alignas,它允许您指定成员应具有的精确对齐方式(VS 2012)应该支持它iirc)。

See the result of using alignas.

答案 1 :(得分:0)

对齐不应更改对象的大小,只是对象的起始地址。例如,一个8字节对齐的对象可能位于地址0x100000或0x100008,或实际上以十六进制写入但不是0x100004时以0或8结尾的任何地址。

答案 2 :(得分:0)

没有

Aligment 2很好。

你有2个字符彼此相邻,这意味着你有4个字节中的2个使用。打包将它与4个字节对齐,然后最终得到4 + 4 +4。

如果您想要最多16个,您可以尝试以下声明:

 {
      char a;
      int b;
      char c;
      int d;
 }