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|