class存储空间,字节对齐

首先: 以下所有试验在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里运行估计结果会有差异。

#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值