2013-04-28 62 views
0

不同的排序相同的结构//我在主体功能使这些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; 
} 

回答

1

第一册的大小为16个字节,但第二册的大小为24个字节//为什么这是否发生?

对齐和填充。

char*成员的大小为8个字节,编译器希望将它与8字节的边界对齐。

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

随着一个int之前,并且一个所述char*之后,编译器插入4个字节填充的第一intchar*之间具有如果结构是8字节对齐后8字节对齐,并且另外4第二个int成员之前或之后(更可能)的填充字节的结构大小是其成员之一所需的最大对齐的倍数(这是char*的8字节要求)。

+0

谢谢你澄清,这很有趣。 – 2013-04-28 22:17:20

0

不同大小的原因是因为填充。在64位机器上,您正在查看8x8地址。 int通常(尽管并非总是)是32位值。您可以将两个int值打包到单个64位空间中。所以下面的结构使用了两个64位块...

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

相反,你的第二个结构宿两个整数之间的指针,它们不能被一起打包成一个单一的64位块,所以你必须留出8第一个8字节,第二个8字节,第二个int保留64位机器的打包规则。

0

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

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

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

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