class存储空间,字节对齐

22 篇文章 0 订阅

 首先: 以下所有试验在32位机,VC.Net2003上运行。 class的存储空间有四点需要注意。
1。默认情况下以最大储存空间变量对齐。double-8,int-4,char-1,short-2,float-4,指针-4,虚函数-4,其实虚函数就是一个指针。以最大的对齐。存储空间必须是要对齐的字节个数的整数倍。
2。 变量及虚函数的存储位置首地址必须是自身所占字节个数的整数倍。 3。可以使用#pragma pack设置要对齐的字节个数,pack()中的值只能是1,2,4,8,16,其他值无效,无效时以第1条,最大存储空间的变量为准。并且当设置的值超 过了最大变量存储字节数的时候,也设置无效,取成员变量中最大字节数的那个为准。
4。成员变量和虚函数(包括虚拟析构函数)占存储空间,一般 成员函数,静态成员函数,静态成员变量不占存储空间。在VC.Net下,成员变量和虚函数分开计算,分别补齐。但是在c++builder里,ms是算在 一起的。所以下面这份代码在c++builder里运行估计结果会有差异。

C++代码
#include <stdio.h>

class a
{        
     char    d2; //0,7        double    d1; //8-15,        int  d3; //16-19,        char    d4; //20, short    d5; //22-23,        float    d6; //24-27,31    };       class a0{         double    d1; //0-7,        char    d2; //8,    short    d5; //10-11,        char    d4; //12,        int        d3; //16-19,        float    d6; //20-23,   
};      
class a1
{        
    char    d2; //0,7        double    d1; //8-15,        int        d3; //16-19,        char    d4; //20,        short     d5; //22-23,        float    d6; //24-27,31           a1(){}        ~a1(){}         void fn1(){}         virtual void        fn2(){} //32-35,39   
};      
class a2
{        
double    d1; //0-7,        char    d2; //8,        short    d5; //10-11,        char    d4; //12,        int        d3; //16-19,        float    d6; //20-23,           a2(){}         virtual ~a2(){} //24-27,        void fn1(){}         virtual void fn2(){} //28-31,    };        
#pragma pack(1)   
class a11
{         char    d2; //0,        double    d1; //1-8,        int        d3; //9-12,        char    d4; //13,        short    d5; //14-15,        float    d6; //16-19,           a11(){}        ~a11(){}         void fn1(){}         virtual void fn2(){} //20-23,   
};   
  #pragma        #pragma pack(2)   
class a12
{         char    d2; //0,1        double    d1; //2-9,        int        d3; //10-13,        char    d4; //14-15,        short    d5; //16-17,        float    d6; //18-21,           a12(){}        ~a12(){}         void fn1(){}         virtual void fn2(){} //22-25,   
};    
#pragma        #pragma pack(4)   
class a14
{       
  char    d2;         double    d1;         int        d3;         char    d4;         short    d5;         float    d6;           a14(){}        ~a14(){}         void fn1(){}         virtual void fn2(){}    
};   
  #pragma        #pragma pack(16)//16这个值无效,因为所有成员变量中,最大的为double的8,超过了8无效,仍然取8   
class a116
{         char    d2; //0,7        double    d1; //8-15,        int        d3; //16-19,        char    d4; //20,        short    d5; //22-23,        float    d6; //24-27,31           a116(){}        ~a116(){}         void fn1(){}         virtual void fn2(){} //32-35,39   
}; 
  #pragma        #pragma pack(3)//3这个值无效,取默认double的8   
class a13
{        
char    d2; //0,7        double    d1; //8-15,        int        d3; //16-19,        char    d4; //20,        short    d5; //22-23,        float    d6; //24-27,31           a13(){}        ~a13(){}         void fn1(){}         virtual void fn2(){} //32-35,39   
};    
#pragma       
class b    
{         char    d1;         int     d2;         short   d3;    
};      
class b0    {         char    d1;         short   d2;         char    d3;    };      
class b1    {         short   d1;         char    d2;    };      
#pragma pack(4)//设置无效,因最大的为short的2,设置4无效,仍然取2   
class b14    
{         short   d1;         char    d2;    };     #pragma        int _tmain( int argc, _TCHAR* argv[])    {         char*   pInt;        printf( "sizeof(char)=%d ", sizeof( char)); //1        printf( "sizeof(double)=%d ", sizeof( double)); //8        printf( "sizeof(int)=%d ", sizeof( int)); //4        printf( "sizeof(short)=%d ", sizeof( short)); //2        printf( "sizeof(float)=%d ", sizeof( float)); //4        printf( "sizeof(char*)=%d ", sizeof(pInt)); //4           printf( "sizeof(a)=%d ", sizeof(a)); //32        printf( "sizeof(a0)=%d ", sizeof(a0)); //24        printf( "sizeof(a1)=%d ", sizeof(a1)); //40        printf( "sizeof(a2)=%d ", sizeof(a2)); //32           printf( "sizeof(a11)=%d ", sizeof(a11)); //24        printf( "sizeof(a12)=%d ", sizeof(a12)); //26        printf( "sizeof(a14)=%d ", sizeof(a14)); //28        printf( "sizeof(a116)=%d ", sizeof(a116)); //40        printf( "sizeof(a13)=%d ", sizeof(a13)); //40           printf( "sizeof(b)=%d ", sizeof(b)); //12        printf( "sizeof(b0)=%d ", sizeof(b0)); //6        printf( "sizeof(b1)=%d ", sizeof(b1)); //4        printf( "sizeof(b14)=%d ", sizeof(b14)); //4              return 0;    }    
以上注释中的结果是在32位机,VC.Net2003下的结果。
如果是在TC3.0上的话,由于tc是16位编译器,结果会不一样。
在tc里char-1,int-2,short-2,float-4,double-8,指针-2。所有均为紧凑对齐,没有字节对齐。即相当于pack(1)。
具体结构,大家可以自行试验。
在linux下用g++编译后结构也不同:结果如下
sizeof(char)=1
sizeof(double)=8
sizeof(int)=4
sizeof(short)=2
sizeof(float)=4
sizeof(char*)=4
sizeof(a)=24
sizeof(a0)=24
sizeof(a1)=28
sizeof(a2)=28
sizeof(a11)=24
sizeof(a12)=26
sizeof(a14)=28
sizeof(a116)=28
sizeof(a13)=28
sizeof(b)=12
sizeof(b0)=6
sizeof(b1)=4
sizeof(b14)=4
可见在g++中,不会跟double的对齐,而是统一跟4对齐。由b,b0,b1也可以看出g++也是和最大成员变量看齐
唯一区别就是g++中最大的是4,而VC.Net中最大的为8。
至于vc.net编译的时候显示的warning中说pack中的值可以为16,就不知道怎么回事了?
难道有占16个字节的基本类型?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值