您的位置:首页 > 其它

结构体与共用体的内存分配问题

2017-06-21 10:36 218 查看
以前单纯以为结构体 共用体的内存大小只需要算出每个成员的内存大小求总和就是了,慢慢才知道并不是这样。

那么为什么会出现内存对齐呢,

大部分的参考资料都是如是说的:

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语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: