sizeof给我的结构带来意想不到的结果

时间:2013-03-17 22:00:45

标签: c++ memory alignment sizeof memory-alignment

我的代码中有这个结构:

struct BlockDescriptor
{
    struct BlockDescriptor * pNext;
    bool _isFree;
};

我倾向于认为它的大小为4 + 1 = 5(指针为4,1bool),但由于某种原因sizeof(struct BlockDescriptor)返回8!有人可以告诉我为什么吗?

是否因为打包问题将5舍入到4的倍数(因为32位是大多数计算机最适合的)并且有某种方法可以强制它使用真正的大小(如果是事实真的大小)?

3 个答案:

答案 0 :(得分:1)

默认情况下,struct的数据成员正在对齐。这些数据成员之间可能存在填充以及最后一个数据成员之后的填充。在你的情况下,填充最有可能在最后。

第一个数据成员是一个指针,在您的情况下需要4个字节的内存。然后虽然另一个成员是char只需要1个字节的内存,但是有一个填充到4的倍数,但原因不是因为“32位是大多数计算机最舒服的正如你所说,“,但因为4是最大数据成员的大小。

通常有一个pragma指令允许您指定可用的自定义对齐方式。在Visual Studio中,有#pragma pack,在这种情况下可能对您有所帮助。只要确保你知道自己在做什么。尽管您将最小化内存使用量,但它可能会对代码的性能产生负面影响。

有关更多信息,请查看相关问题:
How to minimize the memory usage of a struct-type?
How does sizeof calculate the size of structures
Is the size of a struct required to be an exact multiple of the alignment of that struct?
甚至是Determining the alignment of C/C++ structures in relation to its members

答案 1 :(得分:0)

发布答案:Luka Rahne和cnicutar

pNext和_isFree之间有填充。您可以通过编译器特定的机制强制执行“打包”,在结构定义

之前放置#pragma pack(1)

答案 2 :(得分:0)

当CPU访问内存以获取数据项(或结构成员)时,它实际上向内存控制器发送请求,这会执行一些技巧以使DRAM看起来是结构良好的数据存储。实际上,DRAM是一堆单元,每行排列成M行N位(其中N可能是一千个左右)。

了解大多数体系结构一次处理4个,8个,16个或32个(或有时更大的)位,内存控制器针对从4的倍数的地址进行优化。当从地址获取单个字节时会发生什么情况abcd1002?好吧,内存控制器从地址abcd1000中取出四个字节,然后移位它们以获得第三个字节(记住,它是0,1,然后是2),并为您提供糟糕的非对齐字节。因此,从对齐的地址获取总是比从未对齐的地址获取更快。

意识到这一点,编译器通过填充数据结构积极优化速度,以便以对内存友好的方式进行布局。

希望在这个问题上提供重要的计算机体系结构视角。我没有在当前的任何回复中看到这一点,因此我觉得要加上我的0.02美元。

相关问题