https:///syyyy712/article/details/80212551
总结:
要求内存对齐;
遵循原则:
1)最小的字节倍数是4,即如果没有比4个字节更大的类型;
2)sizeof(T)大小是T中最大类型的倍数,比如double的8倍;
3)当出现字节数更大的类型时,确保前面的元素的字节总个数是它的整倍数;后面也是;
有的时候,在脑海中停顿了很久的“显而易见”的东西,其实根本上就是错误的。就拿下面的问题来看:
struct T
{
char ch;
int i ;
};
使用sizeof(T),将得到什么样的答案呢?要是以前,想都不用想,在32位机中,int是4个字节,char是1个字节,所以T一共是5个字节。实践出真知,在VC6中测试了下,答案确实8个字节。哎,反正受伤的总是我,我已经有点麻木了,还是老老实实的接受吧!为什么答案和自己想象的有出入呢?这里将引入内存对齐这个概念。
二 内存对齐概念及其提出的原因
许多计算机系统对其内置类型的存放位置有一定的,通常会按照一定的倍数k存放相应的类型,这种方式即为内存对齐。其中k称为内存模数。
DEF:若sizeof(struct S1)/sizeof(struct S2)>1 则称S1的对齐要比S2的对齐严格,反之相反。
为什么要提出内存对齐?
三 一些例子(在vc的编译器上)
下面用前面的例子来说明VC到底怎么样来存放结构的。
struct MyStruct
{
double dda1;
char dda;
int type
};
面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况:
struct MyStruct
{
char dda;
double dda1;
int type
};
这个结构占用的空间为多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)为24。结合上面提到的分配空间的一些原则,分析下VC怎么样为上面的结构分配空间的。(简单说明)
struct MyStruct
{
char dda;//偏移量为0,满足对齐方式,dda占用1个字节;
double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8
//的倍数,需 要补足7个字节才能使偏移量变为8(满足对齐
//方式),因 此VC自动填充7个字节,dda1存放在偏移量为8
//的地址上, 它占用8个字节。
int type;//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍
//数,满足int的对齐方式,所以不需要VC自动填充,type存
//放在偏移量为16的地址上,它占用4个字节。
};
//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构
//的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof
//(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为
//sizeof(double)=8的倍数。
所以该结构总的大小为:sizeof(MyStruc)为1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西。
VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。
四 自定义对齐方式
否则必须为n的倍数。下面举例说明其用法。
pragma pack(push) //保存对齐状态
pragma pack(4)//设定为4字节对齐
struct test
{
char m1;
double m4;
int m3;
};
pragma pack(pop)//恢复对齐状态
以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。(请读者自己分析)
2、 sizeof用法总结
在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。
A.参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。(https:///seu2hit/article/details/8772314)
B.参数为数组或指针。下面举例说明.
int a[50]; //sizeof(a)=4*50=200;求数组所占的空间大小
int *a=new int[50];// sizeof(a)=4; a为一个指针,sizeof(a)是求指针
//的大小,在32位系统中,当然是占4个字节;位系统是8个字节;
第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一
下面举例说明,
Class Test{int a;static double c};//sizeof(Test)=4.
Test *s;//sizeof(s)=4,s为一个指针。
Class test1{ };//sizeof(test1)=1;