【问题标题】:Different sizes for same structure with different ordering in types相同结构的不同尺寸,不同类型的排序
【发布时间】:2013-04-28 22:07:13
【问题描述】:
//我做了这2个结构体
struct Book1
{
int genre;
int year;
char* author;
};
struct Book2
{
int genre;
char* author;
int year;
};
//在我的主要功能中,我为这两种结构都做了“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;
}
【问题讨论】:
标签:
c
memory
sizeof
ram
structure
【解决方案1】:
Book1 的大小为 16 字节,而 Book2 的大小为 24 字节 //为什么会这样?
对齐和填充。
char* 成员的大小为 8 字节,编译器希望将其对齐在 8 字节边界上。
在char* 之前有两个int 成员 - 每个大小为 4 - 在char* 之前彼此相邻,这在整个结构对齐到 8 个字节并且没有插入填充时自然实现。
在int 之前和char* 之后有一个,编译器在第一个int 和char* 之间插入4 个字节的填充,以使后一个8 字节对齐,如果结构是8-字节对齐,并在第二个int 成员之前或之后(更可能)再填充 4 个字节,使其结构大小是其成员之一所需的最大对齐的倍数(这是 8 字节的要求char*)。
【解决方案2】:
大小不同的原因是填充。在 64 位机器上,您正在查看 8x8 地址。 int 通常是一个 32 位的值,但并不总是如此。您可以将两个 int 值打包到一个 64 位空间中。所以下面的结构使用了两个64bit的块...
struct Book1
{
int genre;
int year;
char* author;
};
相反,您的第二个结构将指针放在两个整数之间,它们不能一起打包成一个 64 位块,因此您必须为前 8 个保留 8 个字节,为指针保留 8 个字节,为指针保留 8 个字节第二个 int 保留 64 位机器的打包规则。
【解决方案3】:
结构是padded 以对齐数据元素。您可以通过
禁用填充
#pragma pack(push, 1)
// your struct here
#pragma pack(pop)
但您通常不希望这样做,因为未对齐的数据可能需要多次内存读取。
【解决方案4】:
padding 问题,在 64bit 架构上,通常对齐是 64bits,也就是 8bytes。
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
};