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 位架构。这是因为d
是int64_t
,它必须在 8 字节边界对齐,所以必须将填充 6 添加到 c
。如果d
是int32_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 内核 内存管理分区伙伴分配器 ② ( free_area 空闲区域结构体源码 | 分配标志位 | GFP_ZONE_TABLE 标志位区域类型映射表 |分配标志位对应的内存区域类型 )
在 64 位处理器上为 3 Point 结构分配了多少字节?
Linux 内核 内存管理memblock 分配器 ③ ( memblock_region 内存块区域 | memblock_region 结构体成员分析 | memblock 分配器标志位 )