内存对齐之学会计算结果

内存对齐的原理, 很多地方都有说,总结一句话: 为了寻址更快,以空间换时间。计算的时候遵循下面四个原则就行了。

四个原则

1.结构体变量的首地址能够被其最宽基本类型成员的大小所整除
2. 结构体每个成员相对于结构体首地址的偏移量都是当前成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
4.如果结构体重嵌套结构体,内部结构体也要遵循第一个原则(内嵌结构体的首个变量的偏移是整个结构体最宽类型成员大小的整数倍。)
5.如果结构体中含有数组,把数组拆开,例如有char[5],等同于char a,char b,char c,char d,char e

下面通过几个例子加深理解。todo:下面的例子都是在4字节对齐,vs2013运行的,括号代表是填充的字节
1.struct test1 {
int a;
char b;
short c;
char d;
};
test1 结构体的最宽是int 占4个字节
a是首元素,所以它的地址就是整个结构体的地址,偏移量0,0/4=0,是整数倍,满足条件1
b占1字节,偏移量是4,4/1=4,满条件2
c占2个字节,偏移量5 ,5/2=2.5,不满足2,给b填字节,填1个字节,因为6/2=3,满足条件2,
d占1个字体,偏移量是8,满足 8/1=整数,目前总共是9,9/4~=条件3,所以要在d后面填3个字节,达到12/4=整数
sizeof(test1)=12
正确的偏移如下:
a:0,1,2,3
b:4,(5)
c:6,7
d:8,(9,10,11)

2.struct test2
{
void* a;
char b[7];
char c[3];
char *d;
char e;
double f;
int g;
};
test2结构体的最宽是double,8个字节
正确的偏移如下:
a:0,1,2,3
b:4,5,6,7,8,9,10
c:11,12,13,(14,15)
d:16,17,18,19
e:20,(21,22,23)
f:24,25,26,27,28,29,30,31
g:32,33,34,35,(36,37,38,39)
sizeof(test2)=40

3.struct test3
{
char a1;
int i;
struct
{
char c[5];
char v;
double b1;
} ss;
int k;
char* m[6];
};
test3结构体的最宽是double,8个字节,嵌套了结构体
正确的偏移如下:
a1:0,(1,2,3)
i:4,5,6,7
ss.c:8,9,10,11,12
ss.d:13,(14,15)
ss.b1:16,17,18,19,20,21,22,23
k:24,25,26,27
m:28~52,(53,54,55)
sizeof(test3)=56

4.struct test4
{
short i;
struct
{
char c;
int j;
} ss;
int k;
};
test4结构体的最宽是int,嵌套结构体
正确的偏移如下:
i:0,1,(2,3)
ss.c:4,(5,6,7)
ss.j:8,9,10,11
k:12,13,14,15
sizeof(test4)=16

5.struct test5
{
char i;
struct
{
char c;
int j;
} ss;
char num[5];
};
test5结构体的最宽是int,嵌套结构体
正确的偏移如下:
i:0,(1,2,3)
ss.c:4,(5,6,7)
ss.j:8,9,10,11
num:12,13,14,15,16,(17,18,19)
sizeof(test5)=20

6.struct test6
{
struct
{
char a;
int b;
}x;
double k;
char c[10];
};
test6结构体的最宽是double,嵌套结构体
正确的偏移如下:
x.a:0
x.b:1,2,3,4,(5,6,7)
k:8,9,10,11,12,13,14,15
c:16~25,(26,27,28,29,30,31)
sizeof(test6)=32

7.struct test7
{
char m[7];
struct
{
char a;
int b;
}x;
double k;
};
test7结构体的最宽是double,嵌套结构体
正确的偏移如下:
m:0~6,(7)
x.a:8,9,10,11
x.b:12,13,14,15
k:16~23
sizeof(test7)=24

8.struct test8
{
char m[7];
struct
{
char a;
int b;
struct str{
char v[3];
int p;
}c;
}x;
double k;
};
test8结构体的最宽是double,嵌套了2层结构体
正确的偏移如下:
m:0~6,(7)
x.a:8,(9,10,11)
x.b:12,13,14,15
x.c.v:16,17,18,(19)
x.c.p:20,21,22,23
k:24~31
sizeof(test8)=32

参考链接1
参考链接2

猜你喜欢

转载自blog.csdn.net/fanzhang1990/article/details/80272568