关于结构体内存对齐规则的整理及思考
2014-04-04 23:21
274 查看
最近两天看了一些关于结构体内存对齐的文章,便想把它们整理一下,也加入了一点自已的思考,只当为自己理清思路,如果有误,还望大家指正。
2.1 一个结构体对象的起始地址(也等于该结构体对象的第一个数据成员的地址),一定是该结构体中最大成员的整数倍;
2.2 结构体的数据成员中,第一个数据成员的的偏移量为0,其余数据成员的偏移量,必须是其自身大小的整数倍;
2.3 结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要在最后一个数据成员之后补齐;
2.4 如果一个结构体A中包含有另一结构体B或数组(数组此时可看做特殊的结构体),则B在A中的偏移量必须是B中最大数据成员的整数倍。
规则2.1中,规定B应该是该结构体中最大数据成员的整数倍,也就意味着,B是该结构体中每一个数据成员大小的整数倍,再加上规则2.2,就可以保证,该结构体对象中每一个数据成员都可以满足结构体内存对齐的要求(第二段中红字)。
对于单个结构体对象,规则2.1和2.2足以使其满足结构体内存对齐的要求,之所以还要满足规则2.3,是出于对结构体数组的考虑。对于结构体数组而言,需要让该数组中的每一个元素都满足规则2.1和2.2,但对于任何数组,数组中的元素都必须连续存储,所以在有些情况下,就必须对结构体进行补齐。而只要满足了规则2.3,就恰好可以确保结构体数组中的每一个元素都满足规则2.1和2.2。
接下来考虑复杂一点的问题,考虑如下定义的2个结构体:
结构体M的对象m作为了结构体N的数据成员。遇到这种情况时,对于结构体M的内存是如何对齐的,我想看了前边的分析后大家应该都比较清楚,而对于结构体N,其包含的数据成员m,是否应该当做一个整体来对待?我们最终的目的,是使得N中所有的数据成员(包括包含在m中的c和d),都满足结构体内存对齐的要求。我们知道如何让N中的数据成员i对齐,那么如何让m中的c和d也对齐呢,c和d在m中的偏移量由规则2.2指出,而c和d的最终地址,还得加上m的地址,而m的地址又等于m在N中的偏移量加上N的地址,所以就有了规则2.4,要求m在N中的偏移量应等于m中最大数据成员的整数倍,同时要求,N的起始地址,应当是N的所有数据成员(即i,c,d)中,占用空间最大的那一个(即d)的整数倍。
1.http://www.ibm.com/developerworks/library/pa-dalign/
2.http://blog.csdn.net/21aspnet/article/details/6729724
3.http://blog.csdn.net/hairetz/article/details/4084088
一、为什么要内存对齐
内存对齐,主要是为了提高CPU的效率。关于这个问题,这篇文章讲得很好《Data alignment: Straighten up and fly right》,我怕自己表述不清楚,所以还是请大家直接看这篇文章。二、结构体内存对齐的规则
结构体内存对齐的要求,就是要确保结构体中的每一个数据成员,其起始地址是该数据成员所占字节数的整数倍。为了满足这一要求,便有了如下这些规则:2.1 一个结构体对象的起始地址(也等于该结构体对象的第一个数据成员的地址),一定是该结构体中最大成员的整数倍;
2.2 结构体的数据成员中,第一个数据成员的的偏移量为0,其余数据成员的偏移量,必须是其自身大小的整数倍;
2.3 结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要在最后一个数据成员之后补齐;
2.4 如果一个结构体A中包含有另一结构体B或数组(数组此时可看做特殊的结构体),则B在A中的偏移量必须是B中最大数据成员的整数倍。
三、为什么会有上述四条规则
我们知道,一个结构体对象中,某数据成员的地址(记为A),应该等于该结构体对象的起始地址(记为B),加上该数据成员在该结构体中的偏移量(记为C)。即:A = B + C,要保证A为该数据成员大小的整数倍,一种可行的方法是让B和C都为该数据成员大小的整数倍。规则2.1中,规定B应该是该结构体中最大数据成员的整数倍,也就意味着,B是该结构体中每一个数据成员大小的整数倍,再加上规则2.2,就可以保证,该结构体对象中每一个数据成员都可以满足结构体内存对齐的要求(第二段中红字)。
对于单个结构体对象,规则2.1和2.2足以使其满足结构体内存对齐的要求,之所以还要满足规则2.3,是出于对结构体数组的考虑。对于结构体数组而言,需要让该数组中的每一个元素都满足规则2.1和2.2,但对于任何数组,数组中的元素都必须连续存储,所以在有些情况下,就必须对结构体进行补齐。而只要满足了规则2.3,就恰好可以确保结构体数组中的每一个元素都满足规则2.1和2.2。
接下来考虑复杂一点的问题,考虑如下定义的2个结构体:
struct M { char c; double d; }; struct N { int i; M m; };
结构体M的对象m作为了结构体N的数据成员。遇到这种情况时,对于结构体M的内存是如何对齐的,我想看了前边的分析后大家应该都比较清楚,而对于结构体N,其包含的数据成员m,是否应该当做一个整体来对待?我们最终的目的,是使得N中所有的数据成员(包括包含在m中的c和d),都满足结构体内存对齐的要求。我们知道如何让N中的数据成员i对齐,那么如何让m中的c和d也对齐呢,c和d在m中的偏移量由规则2.2指出,而c和d的最终地址,还得加上m的地址,而m的地址又等于m在N中的偏移量加上N的地址,所以就有了规则2.4,要求m在N中的偏移量应等于m中最大数据成员的整数倍,同时要求,N的起始地址,应当是N的所有数据成员(即i,c,d)中,占用空间最大的那一个(即d)的整数倍。
四、参考
1.http://www.ibm.com/developerworks/library/pa-dalign/2.http://blog.csdn.net/21aspnet/article/details/6729724
3.http://blog.csdn.net/hairetz/article/details/4084088
相关文章推荐
- 关于结构体内存对齐
- 结构体在内存中的对齐规则
- 关于结构体内存对齐
- C语言--结构体的内存对齐规则
- 关于结构体内存对齐
- 结构体内存对齐规则总结-整体单个排列/成员之间没有边界只有最后的填充/最后是最大类型整数倍
- 结构体在内存中的对齐规则
- 在结构体中内存对齐的规则及其重要性
- 字节字符和整数转换-大小端转换-结构体内存(文件)对齐规则之总结
- 结构体在内存中的对齐规则
- 结构体在内存中的对齐规则 .
- 结构体内存对齐规则
- 【LVL1_6_c】【思考】X86 c语言结构体数据对齐的规则
- 结构体在内存中的对齐规则
- 结构体在内存中的对齐规则
- 结构体在内存中的对齐规则
- 关于内存对齐问题的一些资料整理
- 关于C内存组织方式____结构体对齐
- 结构体和联合体的大小,结构体内存对齐的原因、规则以及柔性数组
- 由结构体对齐而引发的思考(三)——考虑虚基类时c++类对象内存情况