好吧,看完Size of structure with a char, a double, an int and a t后,我仍然没有达到我的结构的大小:
struct s {
char c1[3];
long long k;
char c2;
char *pt;
char c3;
}
并sizeof(struct s)
返回40
但根据我提到的帖子,我认为记忆应该是这样的:
0 1 2 3 4 5 6 7 8 9 a b c d e f
+-------------+- -+---------------------------+- - - - - - - -+
| c1 | |k | |
+-------------+- -+---------------------------+- - - - - - - -+
10 11 12 13 14 15 16 17
+---+- -+- -+- - - - - -+----+
|c2 | |pt | | c3 |
+---+- -+- -+- - - - - -+----+
我应该18
而不是40
...
有人可以向我解释我做错了什么吗?非常感谢你!
答案 0 :(得分:6)
假设long long
和指针上有8字节的指针大小和对齐要求,那么:
c1
k
c2
pt
c3
最多可增加40个字节。
分配尾部填充,以便结构的数组保持结构的所有元素正确对齐。
请注意,大小,对齐要求以及填充因素取决于计算机硬件,编译器和平台的ABI(应用程序二进制接口)。我使用的规则是通用规则:需要在N字节边界上分配N字节类型(对于{1,2,4,8,16}中的N)。数组(在结构的结构和数组中)也需要正确对齐。你有时可以使用#pragma
指令填充填充;要小心。通常最好在开始处布置最严格对齐的对象,最后对齐不太严格的对象。
如果您使用:
struct s2 {
long long k;
char *pt;
char c1[3];
char c2;
char c3;
};
所需的大小只有24个字节,只有3个字节的尾随填充。订单确实很重要!
答案 1 :(得分:2)
结构的大小取决于使用的编译器和启用的编译器选项。 C语言标准对编译器创建结构时如何使用内存没有任何承诺,并且即使使用相同的编译器,不同的体系结构(例如32位WinTel与64位WinTel)也会导致不同的布局决策。
本质上,结构的大小等于字段元素所需的字节大小(通常可以计算)加上编译器注入的填充字节之和(通常不知道) )。
答案 2 :(得分:0)
由于对齐,gcc已经
#pragma pack(push,n)
// declare your struct here
#pragma pack(pop)
改变它。 Read here以及__attribute__((__packed__))
。
如果声明结构
struct packed
{
char c1[3];
long long k;
char c2;
char *pt;
char c3;
} __attribute__((__packed__));
然后使用gcc
,sizeof(packed) = 18
进行编译,因为
c1: 3
k : 8
c2: 1
pt: 4 // it depends
c3: 1
显然Visual C++编译器也支持#pragma pack(push,n)
。