Chinaunix首页 | 论坛 | 博客
  • 博客访问: 154683
  • 博文数量: 70
  • 博客积分: 2050
  • 博客等级: 大尉
  • 技术积分: 690
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-22 22:04
文章分类

全部博文(70)

文章存档

2014年(1)

2013年(1)

2012年(3)

2011年(48)

2010年(17)

我的朋友

分类: WINDOWS

2011-03-11 11:17:51

编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。

Char    自身对齐值1

Short               2

Int long float         4

Double             8

 
struct s1
{
char a;
double b;
int c;
char d;
};

struct s2
{
char a;
char b;
int c;
double d;
};

struct s3
{
int a;
static int b;
};

cout<
cout<cout << sizeof(s3) << endl; //4 (sizeof只计算栈中分配的空间大小)

 
同样是两个char类型,一个int类型,一个double类型,但是因为对齐问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。
 
对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素ddouble类型,要放到8的对界上,离1最接近的地址是8了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是416可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24
 
对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。

 
这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:
struct s1
{
char a[8];
};

struct s2
{
double d;
};

struct s3
{
s1 s;
char a;
};

struct s4
{
s2 s;
char a;
};
cout<
cout<
cout<
cout<
  s1
s2大小虽然都是8,但是s1的对齐方式是1s28double),所以在s3s4中才有这样的差异。
 
所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素
空类所占空间为1,多重继承的空类所占空间为1
虚继承涉及虚表(虚指针)所占空间为4
char var[10]
int test(char var[])
{
return sizeof(var)
};
输出结果为4,此时var[]等价于*var,已经退化为一个指针了。
阅读(334) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~