MSVC默认内存对齐为8

时间:2011-12-07 04:36:40

标签: c++ visual-c++ padding memory-alignment

根据MSDN/Zp命令默认为8,这意味着使用64位对齐边界。我一直认为对于32位应用程序,MSVC编译器将使用32位边界。例如:

struct Test
{
   char foo;
   int bar;
};

编译器会像这样填充它:

struct Test
{
   char foo;
   char padding[3];
   int bar;
};

因此,由于默认使用/Zp8,这是否意味着我的填充使用上面的相同示例变为7 + 4字节:

struct Test
{
   char foo;
   char padding1[7];
   int bar;
   char padding2[4];
}; // Structure has 16 bytes, ending on an 8-byte boundary
这有点荒谬不是吗?我误会了吗?为什么使用如此大的填充物,似乎浪费了空间。 32位系统上的大多数类型甚至不会使用64位,因此大多数变量都有填充(可能超过80%)。

2 个答案:

答案 0 :(得分:9)

这不是它的工作原理。成员对齐其大小的倍数。 Char为1个字节,short为2,int为4,double为8.结构在末尾填充,以确保在数组中使用struct时成员仍然正确对齐。

8的打包意味着它停止尝试对齐大于8的成员。这是一个实际的限制,内存分配器不会返回比8更好的地址。如果没有对齐,则double会非常昂贵正确并最终跨越缓存线。但是如果你编写SIMD代码就会很头疼,它需要16字节对齐。

答案 1 :(得分:3)

这并不意味着每个成员在8字节边界上对齐。仔细阅读一下:

the smaller member type or n-byte boundaries

这里的关键是第一部分 - “较小的成员类型”。这意味着对齐较少的成员可能会更少,更有效地对齐。

struct x {
    char c;
    int y;
};
std::cout << sizeof(x);
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n';
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n';

这会产生8,0,4,这意味着实际上int仅填充到4字节对齐。