1.不同数据类型所占字节的大小
首先说明一下各个类型数据所占字节大小
参考来源:[link](https://www.cnblogs.com/youxin/p/10853511.html).
不同平台下,C和C++数值数据类型长度如下:
需要格外注意的是long这种类型,只有在linux64才为8个字节,像在win32,win64,linux32下都为4个字节,并不是像某些人说的在64位下就是8个字节。此外,指针在32位下为4个字节,64位下为8个字节,这点也需要注意一下。
2.sizeof计算类中或结构体所占空间大小
有了上面的铺垫,才能有如下顺利的进行。计算类中或结构体中数据的大小并不能想当然的将各个数据相加,同时也要个格外注意数据类型的顺序。
2.1 C++语言中空结构体和空类所占内存大小为1
(以下测试都在32位环境下,VS2015测试)
例如(类)这样:
class MyClass
{
public:
MyClass();
~MyClass();
private:
};
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}
.......cout<<sizeof(MyClass)<<endl;.....输出为1
例如(结构体)这样:
struct MyStruct
{
};
......cout << sizeof(MyStruct) << endl;.....输出为1
2.2 满足字节对齐的原则
结构体或类中的总大小为结构体最宽类型成员大小的整数倍。
还有种种对齐原则,看起来比较抽象,不妨举下例子来理解一下。
我的理解方式是前者满足后者的倍数,最后计算的总大小需要满足最宽类型成员的整数倍。
(1)
class MyClass
{
public:
char m1;
int m2;
char m3;
private:
};
.......cout<<sizeof(MyClass)<<endl;.....输出为12
上面的程序,在32位环境下,char占用1个字节,int占用4个字节,char占用1个字节,不能简单的将他们加起来1+4+1=6,这样肯定是不对的,需要满足对齐原则,下面说一下我的理解方式。
首先m1占用1个字节,接着往下看m2,m2是4个字节,根据前者满足后者的倍数,所以计算m2的时候前面所算的大小需要补为m2的倍数即1+3(这个3是为了补m2的倍数,因为1显然不是4的倍数,需要补上一个3),紧接着加上m2的字节数4,再往下看,加上m3的字节数,这时候加起来一共是1+3(补)+4+1=9,又因为结构体或类中的总大小为结构体最宽类型成员大小的整数倍,这个例子显然最宽类型的成员为m2,即为4,最后的结果需要是整数倍,所以需要再次补上3。即为1+3(补)+4+1+3(补)=12。
顺序也很重要,下面颠倒顺序看一下。就会有不一样的结果。
(2)
class MyClass
{
public:
int m1;
char m2;
char m3;
private:
};
.......cout<<sizeof(MyClass)<<endl;.....输出为8
此时m1是4个字节,m2,m3为1个字节,根据前者满足后者的倍数,m1为4满足了m2(m2为1)的倍数,此时不用补了,往下看m3,4+1=5满足m3的倍数,加起来4+1+1=6,最后满足最宽的倍数,即m1的倍数,则4+1+1+2(补)=8,这个类的字节数为8.
再变换一下顺序,如下所示。
(3)
class MyClass
{
public:
char m1;
char m2;
int m3;
private:
};
.......cout<<sizeof(MyClass)<<endl;.....输出为8
此时m3是4个字节,m1,m2为1个字节,根据前者满足后者的倍数,则m1为1满足了m2的倍数,此时为1+1=2,往下看m3,2不满足m3的倍数,需要补2,最后加上m3,即1+1+2(补)+4=8,8正好满足了最宽m3的倍数,这个类即为8个字节。
(4)
下面举一个稍微复杂的例子,
class MyClass
{
public:
char m1;
char m2;
double m3;
int m4 ;
double m5;
short m6;
private:
};
.......cout<<sizeof(MyClass)<<endl;.....输出为40
现在来分析:
m1,m2都为1个字节,m3为8个字节,m4为4个字节,m5为8个字节,m6为2个字节。m1为1当然能满足m2的倍数,m1+m2=2不满足m3的倍数,需要补6,即1+1+6(补)=8,之后加上m3,为8+8=16,16满足m4的倍数,加上m4,即16+4=20,往下看m5,m5为8,显然20不是8的倍数,需要补上4,之后加上m5,即1+1+6(补)+8+4+4(补)+8=32.往下看m6,32为m6的倍数,直接加上就行,32+2=34,最后检查一下是不是最宽类型的倍数,此类最宽类型为double,为8,34不是8的倍数,需要补6,最后的计算结果为1+1+6(补)+8+4+4(补)+8+2+6(补)=40。