0

//我做了这两个结构

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;
}
4

4 回答 4

1

Book1 的大小为 16 字节,而 Book2 的大小为 24 字节 //为什么会这样?

对齐和填充。

char*成员的大小为 8 字节,编译器希望将其对齐在 8 字节边界上。

两个int成员 - 每个大小为 4 - 在 之前彼此相邻char*,当整个结构对齐到 8 个字节并且没有插入填充时自然会实现。

如果结构是 8 字节对齐int的,编译器会在第一个和char*之间插入 4 个字节的填充以使后一个8 字节对齐,并且在之前或之后再插入 4 个字节的填充(更多可能)第二个成员的结构大小是其成员之一所需的最大对齐的倍数(这是 8 字节的要求)。intchar*intchar*

于 2013-04-28T22:12:47.790 回答
0

不同尺寸的原因是因为填充。在 64 位机器上,您正在查看 8x8 地址。int 通常是一个 32 位的值,但并不总是如此。您可以将两个 int 值打包到一个 64 位空间中。所以下面的结构使用了两个 64bit 块...

struct Book1
{
    int genre;  
    int year;
    char* author;       
};

相反,您的第二个结构将指针放在两个 int 之间,它们不能一起打包成一个 64 位块,因此您必须为前 8 个预留 8 个字节,为指针预留 8 个字节,为第二个 int 预留 8 个字节保留 64 位机器的打包规则。

于 2013-04-28T22:12:55.017 回答
0

正在填充结构以对齐数据元素。您可以通过禁用填充

#pragma pack(push, 1)
// your struct here
#pragma pack(pop)

但是您通常不想这样做,因为未对齐的数据可能需要多次内存读取。

于 2013-04-28T22:13:05.440 回答
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
    };
于 2013-04-28T22:26:53.010 回答