//我制作了这两个结构
struct Book1
{
int genre;
int year;
char* author;
};
struct Book2
{
int genre;
char* author;
int year;
};
//在我的main函数中,我为两个结构都做了'sizeof()'。 //由于某种原因,Book1的大小为16字节,但Book2的大小为24字节 //为什么会这样? //顺便说一句,这是在一台64位的Windows机器上,使用Visual Studio 2012进行编译
int main(void)
{
int test1 = sizeof(struct Book1);
int test2 = sizeof(struct Book2);
return 0;
}
答案 0 :(得分:1)
Book1的大小为16字节,但Book2的大小为24字节//为什么会这样?
对齐和填充。
char*
成员的大小为8个字节,编译器希望将其与8字节边界对齐。
使用两个int
成员 - 每个大小为4 - 在char*
之前彼此相邻,当整个结构与8个字节对齐并且没有插入填充时,这自然会实现。< / p>
前一个int
,char*
后面一个,编译器在第一个int
和char*
之间插入4个字节的填充,以使后者8-如果结构是8字节对齐的话,则字节对齐,并且在第二int
成员之前或之后(更有可能)的另外4字节填充,使结构大小为其成员之一所需的最大对齐的倍数(这是char*
的8字节要求。)
答案 1 :(得分:0)
不同尺寸的原因是因为填充。在64位计算机上,您正在查看8x8地址。 int通常(尽管不总是)是32位值。您可以将两个int值打包到一个64位空间中。所以下面的结构使用两个64位块...
struct Book1
{
int genre;
int year;
char* author;
};
相反,你的第二个结构将指针放在两个整数之间,它们不能打包成一个64位的块,所以你必须为前8个字节留出8个字节,为指针留出8个字节,为8个字节留出8个字节。第二个int保留64位机器的打包规则。
答案 2 :(得分:0)
结构正在padded以对齐数据元素。您可以通过
禁用填充#pragma pack(push, 1)
// your struct here
#pragma pack(pop)
但是你通常不想这样做,因为未对齐的数据可能需要多次内存读取。
答案 3 :(得分:0)
填充问题,在64位架构上,通常对齐是64位,即8字节。
struct Book1 //16bytes
{
int genre; //4 bytes
int year; //4 bytes
char* author; //8 bytes
};
struct Book2 //24 bytes
{
int genre; //4 bytes
//4 bytes, padding
char* author; //8 bytes
int year; //4 bytes
//4 bytes, padding
};