【问题标题】:sizeof giving unexpected result for my structure [duplicate]sizeof 给我的结构带来了意想不到的结果[重复]
【发布时间】:2013-03-06 04:40:28
【问题描述】:

我的代码中有这个结构:

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

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

是因为打包问题,5 被四舍五入为 4 的倍数(因为 32 位是大多数计算机最熟悉的),是否有某种方法可以强制它使用真实大小(如果在事实上真实大小)?

【问题讨论】:

  • pNext_isFree 之间的填充。您可以通过特定于编译器的机制强制“打包”。
  • 将#pragma pack(1) 放在结构定义之前。
  • 为什么sizeof(struct BlockDescriptor) 返回的内容对您很重要?
  • @LukaRahne 谢谢你的工作
  • 更改结构中成员的顺序:bool;结构*;你可能会得到 5 个字节,但这是特定于编译器的

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


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    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

    【讨论】:

    • 是的,对齐是由最大数据成员的大小来定义的
    【解决方案3】:

    由 Luka Rahne 和 cnicutar 提供答案

    pNext 和 _isFree 之间有 Padding。您可以通过特定于编译器的机制强制“打包”,将 #pragma pack(1) 放在结构定义之前

    【讨论】:

    • 填充更可能在 _isFree之后,将结构体的大小填充到8字节。
    • @PeteBecker 是的,_isFree 与 4 对齐,这是结构的对齐方式,因为其最大数据成员的大小为 4。
    猜你喜欢
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 2017-11-30
    • 2011-03-21
    • 2017-10-26
    • 2019-05-19
    • 2017-01-05
    • 2021-10-14
    相关资源
    最近更新 更多