64位系统中结构的内存分配

Posted

技术标签:

【中文标题】64位系统中结构的内存分配【英文标题】:Memory allocation from struct in 64 bit system 【发布时间】:2021-04-10 00:46:23 【问题描述】:

我在通过旧考试时发现了这个问题,我必须在 64 位操作系统上为这个特定结构输入字段大小和填充大小:

struct mystruct 
    char a;
    uint32_t b;
    int16_t c;
    int64_t d;
;

答案是:

struct mystruct 
    char a;     //field size: 1, padding size: 3
    uint32_t b; //field size: 4, padding size: 0
    int16_t c;  //field size: 2, padding size: 6
    int64_t d;  //field size: 8, padding size: 0
;

我确实理解为什么 int16_t 被分配 2 个字节和 6 个填充,因为是 64 位架构。与int64_t 相同。

但是,为什么char 分配有 3 填充大小,uint32_t 分配有 4 字段大小,当它是 64 位架构时?

【问题讨论】:

这是强编译器和 ABI 特定的。不可能有一个普遍的答案! Windows/x86-64 和 Linux/PowerPC 上的情况可能有所不同(即使您使用一些 GCC 编译器)。一些编译器甚至在一些优化过程中重新排列了struct 成员。 I do understand why int16_t gets allocated 2 Bytes and 6 padding, because of the 64 bit architecture - 这不是因为 64 位架构。这是因为dint64_t,它必须在 8 字节边界对齐,所以必须将填充 6 添加到 c。如果dint32_t d;,那么c 将具有字段大小:2,填充大小:2。 好吧,在讲座中我们一直使用 linux,我猜没有像重新排列这样的优化,除了编译器认识到“拆分”第一个 64 位地址以适应 char 和 uint32_t 的可能性. @GSerg 哦好吧,有道理! ***.com/a/38144117/477878 可能会有所帮助。 【参考方案1】:
struct mystruct 
    char a;     //field size: 1, padding size: 3
    uint32_t b; //field size: 4, padding size: 0
    int16_t c;  //field size: 2, padding size: 6
    int64_t d;  //field size: 8, padding size: 0
;

我明白为什么 int16_t 被分配 2 个字节和 6 个填充, 因为64位架构。与 int64_t 相同。但为什么是 char 分配了 3 填充大小和 uint32_t 字段大小为 4 什么时候是 64 位架构?

因为:

char 将从任何偏移量开始。

unit32_t 将从偏移量mod(4) == 0 开始。

int16_t 将从偏移量mod(2) == 0 开始。

int64_t 将从偏移量mode(8) == 0 开始。

因此

 offset  ->   0   1           4    8   10           16            24
              +--------------------+----------------+-------------+
              | a | 3byte pad |  b | c | 6byte pad  |   d         |
              +--------------------+----------------+-------------+

【讨论】:

以上是关于64位系统中结构的内存分配的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核中常见内存分配函数zz

Linux 内核 内存管理分区伙伴分配器 ② ( free_area 空闲区域结构体源码 | 分配标志位 | GFP_ZONE_TABLE 标志位区域类型映射表 |分配标志位对应的内存区域类型 )

在 64 位处理器上为 3 Point 结构分配了多少字节?

在 R 中使用自定义内存分配函数

Linux 内核 内存管理memblock 分配器 ③ ( memblock_region 内存块区域 | memblock_region 结构体成员分析 | memblock 分配器标志位 )

您应该能够分配多少内存?