您的位置:首页 > 其它

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

2011-05-07 19:36 330 查看
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字节,但由于A是8字节对齐的,所以int n和char 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后面无需填充,
作为尾项,c,10-〉16
struct B的内存空间如下:
| 4 |...| 4 | 4 | 4 | 4 | 4 |...|10->16|
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: