结构体与共用体的内存分配问题
2017-06-21 10:36
218 查看
以前单纯以为结构体 共用体的内存大小只需要算出每个成员的内存大小求总和就是了,慢慢才知道并不是这样。
那么为什么会出现内存对齐呢,
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
那让我们来弄清楚他的对齐规则吧
例:
其实并不是简单的8+4+1+4=17,而是24。为什么呢?
这里最大的基本类型是double,为8字节,所以该结构体是以8字节对齐的,所以是24.
该共用体内存大小为12
最大基本类型是int,而长度为数组b决定的,为10,10不是4的倍数,进行对齐后为12
内存为3,基本类型为char,长度由b数组决定
再来看下面这三种情况
这三种情况结果一样么,你可能会说,都是12,然而并不是这样的struct s1,struct s2是8,然而struct s3是12,为什么呢
三种情况最大基本类型都是int,分配存储空间的时候,编译器知道是以4对齐的,第三种分配时,因为要考虑对齐,所以a得到的存储空间其实是4,b是4,c是4,所以是12
但是前两种没有必要,只需要给两个char型的分配4就够用了,所以是8
稍微复杂一点的来了,s2存储长度是多少呢
最大基本类型是double,长度取决于a,为12,而要与8对齐,所以这个共用体的存储空间是16
这个又占多少呢
答案是24
最长基本类型是double,a b各自分配4,c分配8,d e f加起来是7,所以扔给他们一个8就可以了,所以4+4+8+8=24
这个又是多少呢
这里只变了char数组e[3],那么现在d+e+f所需要的存储空间变成了9,8就不够了,现在就需要进行补齐。d分配4,e分配4,f分配8
4+4+8+4+4+8=32
内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单
a7a8
元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。
那么为什么会出现内存对齐呢,
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
那让我们来弄清楚他的对齐规则吧
例:
struct s { doiuble a; int b; char c; float d; };
sizeof(struct s)是多少呢?
其实并不是简单的8+4+1+4=17,而是24。为什么呢?
这里最大的基本类型是double,为8字节,所以该结构体是以8字节对齐的,所以是24.
union s { int a; char b[10]; };
该共用体内存大小为12
最大基本类型是int,而长度为数组b决定的,为10,10不是4的倍数,进行对齐后为12
union s { char a; char b[3]; };
内存为3,基本类型为char,长度由b数组决定
再来看下面这三种情况
struct s1 { int a; char b; char c; }; struct s2 { char a; char b; int c; }; struct s3 { char a; int b; char c; };
这三种情况结果一样么,你可能会说,都是12,然而并不是这样的struct s1,struct s2是8,然而struct s3是12,为什么呢
三种情况最大基本类型都是int,分配存储空间的时候,编译器知道是以4对齐的,第三种分配时,因为要考虑对齐,所以a得到的存储空间其实是4,b是4,c是4,所以是12
但是前两种没有必要,只需要给两个char型的分配4就够用了,所以是8
struct s { char a; int b; char c; }; union s2 { struct s a; double b; };
稍微复杂一点的来了,s2存储长度是多少呢
最大基本类型是double,长度取决于a,为12,而要与8对齐,所以这个共用体的存储空间是16
struct s { int a; long b; double c; float d; char e; short f; };
这个又占多少呢
答案是24
最长基本类型是double,a b各自分配4,c分配8,d e f加起来是7,所以扔给他们一个8就可以了,所以4+4+8+8=24
struct s { int a; long b; double c; float d; char e[3]; short f; };
这个又是多少呢
这里只变了char数组e[3],那么现在d+e+f所需要的存储空间变成了9,8就不够了,现在就需要进行补齐。d分配4,e分配4,f分配8
4+4+8+4+4+8=32
内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单
a7a8
元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。
相关文章推荐
- 结构体和共用体关于内存的分配问题
- 结构体共用体内存分配问题
- 结构体和共用体关于内存的分配问题
- VC中结构体内存分配问题透析
- VC中结构体内存分配问题透析
- 结构体内存分配问题(转)
- 结构体内存分配问题(转)
- 结构体内存分配问题
- C语言中结构体内存分配问题解析。
- 结构体内存分配问题
- VC中结构体内存分配问题透析(sizeof)
- c语言结构体内存分配问题
- VC中结构体内存分配问题透析
- new和delete对结构体分配内存的问题
- VC中结构体内存分配问题透析(sizeof)
- C语言结构体分配内存问题
- 结构体内存分配问题(转)
- 结构体内存分配问题
- 结构体中的内存分配--struct dirent中引起的问题
- 结构体内存分配问题(转)