现在的位置: 首页 > 综合 > 正文

神秘的sizeof(union和struct的区别)

2017年12月14日 ⁄ 综合 ⁄ 共 1028字 ⁄ 字号 评论关闭

union A

{

         int
a[5];

         char
b;

         double
c;

};

 

struct B

{

         int
n;

         A
a;

         char
c[10];

}

 

sizeof(B) = ?

答案:

union A:

{

         int
a[5]; //20 

         char
b;   //1

         double
c; //8

}

 

我想的是union中变量共用内存,应以最长的为准,那就是20。可实际不然,sizeof(A)=24

A中各变量的默认内存对齐方式,必须以最长的double
8
字节对齐,故应该是sizeof(A)=24

struct B

{

         int
n; // 4
字节

         A
a;   // 24
字节

         char
c[10]; // 10
字节

};

实际占用38字节,但由于A8字节对齐的,所以int nchar c[10]也需要8字节对齐,总共8+24+16=48

内存对齐主要目的是提升读取数据的速度,通过保证
类型数据(n字节)保存在n倍数的内存地址上。(n越大,要求越严格。)

要做到这点,有3个位置要求。

首地址,调到最严格地址倍数上,不影响大小。

中间项,按各自下一项的地址要求填充调整,影响大小。

最后一项,通过填充,达到最严格地址大小倍数,影响大小。

 

union A

{

         int
a[5];

         char
b;  

         double
c;

};

对于union A(共享内存),其实只有一项

至少需要20字节。首地址可以解释为3种类型,

A =a时,

| 4 | 4 | 4 | 4 | 4 | 20字节

中间和尾部都不需调整。

A =b时,

|1|.................|

中间和尾部都不需调整,20字节。

A =c时,

| 8 |...........|

c作为最后项,需要调整20-24

因此,内存布局:

| 4 | 4 | 4 | 4 | 4 |...| (...padding)total=24

 

struct B

{

         int
n;

         A
a;  

         char
c[10];

}

这里要注意a,是作为A类型,是一项数据。

对于 struct B,最严格8字节,

首地址为8的倍数,填入n(后面空4个字节,因为a的开始地址要求8的倍数)

c,开始地址无特殊要求,a后面无需填充,

作为尾项,c10-16

struct B的内存空间如下:

| 4 |...| 4 | 4 | 4 | 4 | 4 |...|10->16|

抱歉!评论已关闭.