结构对齐可能会浪费内存?
Posted
技术标签:
【中文标题】结构对齐可能会浪费内存?【英文标题】:Struct alignment may waste memory? 【发布时间】:2020-02-11 04:34:25 【问题描述】:现在我有一个 struct st,其中包含另一个 struct:
struct st2
char b = 2;
long c = 3;
;
struct st
char a = 1;
st2 mySt;
int d = 4;
char e = 5;
;
当我在内存中检查这个struct st时,它是这样的:
0x7fffffffdce0: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdce8: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdcf0: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdcf8: 0x04 0x00 0x00 0x00 0x05 0x00 0x00 0x00
mySt 的第一个字符似乎是 8 对齐的(在 x64 中,我认为这是使用 struct st2 的大小,而 #pragma pack 默认为 8)。
不过,如果让我设计编译器,我会把mySt拆开,把mySt的每一个基本类型都当作st的,所以成员a和b之间应该没有填充:
struct st
char a = 1;
char b = 2; // unwind mySt
long c = 3; // unwind mySt
int d = 4;
char e = 5;
;
// Now the char a and b can storage in just one qword, by unwinding the sub structure.
0x7fffffffdcf0: 0x01 0x02 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdcf8: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdd00: 0x04 0x00 0x00 0x00 0x05 0x00 0x00 0x00
那么问题来了:为什么编译器没有与每个子结构中的基本类型对齐,而是与整个子结构的大小对齐?这不是浪费内存吗?
【问题讨论】:
【参考方案1】:st2
的所有实例都具有相同的布局。存储对象的位置可能不会影响该布局。对象是否是成员可能不会影响该布局。编译器不能简单地选择mySt
的成员之一并将其存储在对象之外。
考虑将st2
传递给函数:
void some_function(st2&);
该函数无法知道该对象来自何处。但它必须能够访问对象的成员。对象的布局必须在编译时知道。如果st2
的一个实例与另一个实例的布局不同,该函数如何知道?
【讨论】:
以上是关于结构对齐可能会浪费内存?的主要内容,如果未能解决你的问题,请参考以下文章