标签:
字节对齐是面试笔试经常考到的一个知识点
计算一个结构体大小只需要进行如下几个步骤即可。
1.确认结构体中所有成员的长度大小
可以引用此表。
|
|
char |
short |
int |
long |
float |
double |
long long |
long double |
Win-32 |
长度 |
1 |
2 |
4 |
4 |
4 |
8 |
8 |
8 |
模数 |
1 |
2 |
4 |
4 |
4 |
8 |
8 |
8 |
|
Linux-32 |
长度 |
1 |
2 |
4 |
4 |
4 |
8 |
8 |
12 |
模数 |
1 |
2 |
4 |
4 |
4 |
4 |
4 |
4 |
|
Linux-64 |
长度 |
1 |
2 |
4 |
8 |
4 |
8 |
8 |
16 |
2.确定系统默认的对齐模数:
【#pragma pack指定的数值】、【未指定#pragma pack时,vc6 中默认是8】
在下面这种形式下就是自己指定对齐模数。
#pragma pack(2)
struct my_struct
{
char a;
long double b;
};
#pragma pack()
3.此时就会得到一组数和一个数(每个成员的大小 和 系统的模数) 按照以下方法计算即可得到总长度length=0
1.拿出第一个成员的长度加到总长度里面 length += sizeof(member1) 因为对于第一个成员不存在对齐问题 都是从0开始
2.拿出第二个成员的长度,和系统模数比较 拿出较小的数 min
3.在前一个成员后面进行移动,让加上字节后的地址可以被 min整除,第二个成员的其实位置就是这个地址。
4.以此类推
4.最后 拿出所有成员中最大的长度max 和系统模数比较,拿出较小的totalmin,看现在的总长度能不能被totalmin整除,如果可以现在就行了,如果不可以在后面加上n让总长度可以被totalmin整除 最后就是最终大小。
举个例子:
struct my_struct
{
char a;
double b;
};
第一步:获得所有成员的长度:a 的长度是 1 b的长度是 8
第二步:获取系统的模数 此时没有指定pack 所以用vc6中默认的即可 8
第三步:把a算进去 现在总长度是1了,内存布局为[0] 0位置存放的就是a 然后拿出b的长度8 和默认的8比较,取出较小的 也就是8, 此时b所在的位置应该能被8整除
但是我们看 a是从0开始的 a的长度是1 所以 必须把地址向后移动7位,让b的起始地址是8 才能保证被8整除。所以在a和b之间要加入7个空位,然后让b从8开始
[0][1 2 3 4 5 6 7] [8 9 10 11 12 13 14 15]
第四部:总长度为 a + b + 空 = 1 + 8 + 7 = 16
拿出所有成员中最长的b 也就是8 拿出系统默认的8 取较小的8
看16能否被8整除 这里可以,所以最后长度为16
再来个复杂的:
struct my_struct
{
int a;
char b;
double c;
int d;
char e;
};
还是按照那几步骤:
1.获取所有成员的长度 分别是 4 1 8 4 1
2.获取系统模数 这里没自定义pack 所以是 8
3. 第一个成员a 从0位置开始 占据[0123] 四个字节
然后轮到b了。因为a占据0123了 所以b从4开始 b的长度是1 ,和系统模数8比,取出小的 1 。4可以被1整除,不用补空位 此时 [0123][4 ] 0123放着a 4放着b
然后轮到c了,c是8 和系统模数比 取出小的 8 ,01234都有 东西了,c要从5开始,但是5不能被8整除 想要被8整除,最起码要在8这个位置开始 所以567存放空位,c从8开始 此时[0 1 2 3] [4] [5 6 7] [8 9 10 11 12 13 14 15]
现在轮到d了, d是4 系统模式是8 拿出小的 4 起始地址16 能被4整除,所以d就从16开始[0 1 2 3] [4] [5 6 7] [8 9 10 11 12 13 14 15][16 17 18 19]
最后轮到了e, 1和8比 拿出1 起始地址为20 能被1整除,所以最后结构是[0 1 2 3] [4] [5 6 7] [8 9 10 11 12 13 14 15][16 17 18 19][20]
4.最后拿出所有成员中最长的 是c 长度为8 和系统模数8 比 取出小的 8
现在的总长度21不能被8整除,所以仍然要向后补3位[0 1 2 3] [4] [5 6 7] [8 9 10 11 12 13 14 15][16 17 18 19][20][21 22 23]
一共24字节。
注意:
有指针成员,大小按照指针的大小即可。
注意:关于64位系统和32位系统的大小
可以确定的是32位系统的指针大小为32位 也就是4字节
64位系统的指针大小为64位 就是8字节
但是对于int型 long double 等类型,32位64位根据系统不同大小不同。没有确定标准
但是如果出现int32_t 或者 int64_t ,这些是为了保证可移植性而定义的类型,表示32位的int和64位的int,长度分别为固定的32位和64位
标签:
原文地址:http://www.cnblogs.com/heanqing/p/4908360.html