我正在读这个答案:C struct memory layout?并且很想知道原因:
struct ST
{
long long ll;
char ch2;
char ch1;
short s;
int i;
};
仍然是24字节而不是16字节的大小。我期待2 * char + short + int以适应8个字节。为什么会这样?
修改
很抱歉这个混乱,我正在使用64位系统(debian) gcc(Debian 4.4.5-8)4.4.5 。由于填充,我已经知道它了。我的问题是为什么?其中一个答案表明:
char = 1 byte
char = 1 byte
short = 1 byte (why is this 1 and not 2?)
* padding of 5 bytes
我的问题是,为什么这里的填充...为什么不在短路后直接放置 int ,它仍然适合8个字节。
答案 0 :(得分:1)
关于填充的全部内容。在visual studio(以及其他一些编译器)中,您可以使用#pragma push / pack使其按照您的意愿进行对齐。
#pragma pack(push, 1)
struct ST
{
/*0x00*/ long long ll;
/*0x08*/ char ch2;
/*0x09*/ char ch1;
/*0x0a*/ short s;
/*0x0c*/ int i;
/*0x10*/
};
#pragma pack(pop)
既然你说它的大小是24,那么我猜测编译器会通过这样的方式将你对齐4个字节:
struct ST
{
/*0x00*/ long long ll;
/*0x08*/ char ch2;
/*0x09*/ char padding1[0x3];
/*0x0c*/ char ch1;
/*0x0d*/ char padding2[0x3];
/*0x10*/ short s;
/*0x11*/ char padding3[0x2];
/*0x14*/ int i;
/*0x18*/
};
(对不起,我想在做这种事情的时候是十六进制.0x10是十进制的16,0x18是十进制的24。)
答案 1 :(得分:1)
简单的答案是:它不是24个字节。或者您正在使用我无法找到ABI文档的64位s390 Linux端口上运行。 Debian可以运行的每个其他64位硬件的结构大小为16字节。
我已经为一堆不同的CPU ABI挖出了ABI文档,它们或多或少都有这样的措辞(似乎它们都是相互复制的):
结构和联合体假定其最严格对齐的组件对齐。每个成员都被分配到具有适当对齐的最低可用偏移量。任何对象的大小始终是对象对齐的倍数。
我发现的所有架构ABI文档(mips64,ppc64,amd64,ia64,sparc64,arm64)都具有char 1,short 2,int 4和long long 8的对齐方式。
尽管允许操作系统制作自己的ABI,但几乎每个类Unix系统,特别是Linux都遵循System V ABI及其补充CPU文档,这些文档很好地指定了这种行为。并且Debian肯定不会改变这种行为,使其与所有其他Linux不同。
这是一个快速验证(全部在amd64 / x86_64上,这是您最有可能运行的):
$ cat > foo.c
#include <stdio.h>
int
main(int argc, char **argv)
{
struct {
long long ll;
char ch2;
char ch1;
short s;
int i;
} foo;
printf("%d\n", (int)sizeof(foo));
return 0;
}
的MacOS:
$ cc -o foo foo.c && ./foo && uname -ms
16
Darwin x86_64
Ubuntu的:
$ cc -o foo foo.c && ./foo && uname -ms
16
Linux x86_64
CentOS的:
$ cc -o foo foo.c && ./foo && uname -ms
16
Linux x86_64
OpenBSD的:
$ cc -o foo foo.c && ./foo && uname -ms
16
OpenBSD amd64
您的编辑还有其他问题。或者那不是您正在测试的结构,或者您正在一个非常奇怪的硬件架构上运行并将其指定为&#34; 64位&#34;相当于说&#34;我驾驶这种政府发行的车辆,它有非常奇怪的加速度,发动机在5分钟后切断了#34;并没有提到你在谈论航天飞机。
答案 2 :(得分:0)
通常为了最小化填充,通常的做法是从大到小对成员进行排序,您是否可以尝试对它们进行重新排序并查看其中的内容?
struct ST
{
long long ll; //8 bytes
int i; //4bytes
short s; //2 bytes
char ch2; //1 byte
char ch1; //1 byte
};
总计是16个字节