攻城狮凌风

sizeof总结

1.sizeof常用总结

①与strlen比较

      strlen  计算字符串的字符数,以"\0"为结束判断,但不统计结束符。 
     sizeof  计算数据(数组、变量、类型、结构体等)所占内存空间,用字节数表示。

②指针与静态数组的sizeof操作

  指针均可看为变量类型的一种。因此:
      int *p; 
                    sizeof(p)=4;
                    sizeof(*p)=4;//相当于sizeof(int)      

  对于静态数组,sizeof可直接计算数组大小:
      例:int a[10];char b[]="hello";
                    sizeof(a)=40;//4*10=40;
                    sizeof(b)=6;
  数组做型参时,数组名称当作指针使用:
             例: void  fun(char p[]);
                     sizeof(p)=4;

③格式的写法

    sizeof为操作符而非函数,对变量或对象可以不加括号,但若是类型,须加括号。

④操作string的注意事项

        string   str[]={"hello", "world", "CHB","\n"};
        cout<<sizeof(str)<<endl;//输出128
        cout<<sizeof(str[0])<<endl;//输出32,即对象的大小
        cout<<sizeof(str[0].c_str())<<endl;//输出4,c_str()返回 const char*指针,指向str[0]
        cout<<strlen(str[0].c_str())<<endl;//输出5,str[0]字符串的长度

⑤经典问题: 

        double* (*a)[3][6]; 
        cout<<sizeof(a)<<endl; // 4,a为指针
        cout<<sizeof(*a)<<endl; // 72 ,*a为一个有3*6个指针元素的数组
        cout<<sizeof(**a)<<endl; // 24, **a为行指针
        cout<<sizeof(***a)<<endl; // 4 ,***a为一维的第一个指针
        cout<<sizeof(****a)<<endl; // 8 ,****a为一个double变量
       解析a为指向double*[3][6]类型二维指针数组(数组元素为double* 指针类型)的指针。既然是指针,所以sizeof(a)就是4。*a就表示二维指针数组double*[3][6],因此sizeof(*a)=3*6*sizeof(double*)=72**a为行指针,指向一维指针数组double*[6]sizeof(**a)=6*sizeof  (double*)=24***a就表示行指针数组的第一个指针元素,也就是double*了,所以sizeof(***a)=4。至于****a,则是一个double类型,所以sizeof(****a)=sizeof(double)=8

     看看以下情况:
	double**b[3][6]; 
        cout<<sizeof(b)<<endl; // 72,b为数组类型,数组元素为double**;
        cout<<sizeof(*b)<<endl; // 24,行指针
        cout<<sizeof(**b)<<endl; // 4,b[0][0]的值,double**类型
        cout<<sizeof(***b)<<endl; // 4,double* 
        cout<<sizeof(****b)<<endl; // 8 double
	double (*c)[3][6];
	cout<<sizeof(c)<<endl;//4,指针变量,指向double[3][6]
	cout<<sizeof(*c)<<endl;//144,double[3][6]的数组类型
	cout<<sizeof(**c)<<endl;//48,行指针,指向c[0],实际指向为&c[0][0]
	cout<<sizeof(***c)<<endl;//8,c[0][0]的值
	double* d[3][6];
        cout<<sizeof(d)<<endl; // 72,指针数组类型,元素为double*的[3][6]数组
        cout<<sizeof(*d)<<endl; // 24,行指针
        cout<<sizeof(**d)<<endl; // 4,d[0][0]的元素值,即double*
        cout<<sizeof(***d)<<endl; // 8

⑥操作struct的内存对齐问题

     (1)整体空间是占用空间最大的成员(的类型)所占字节数的整倍数
    (2)内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。
    (3)数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。

例子1

  1. struct s1{  
  2.    char a;  
  3.    double b;  
  4.    int c;  
  5.    char d;};  
  6.      
  7. struct s2{  
  8.    char a;  
  9.    char b;  
  10.    int c;  
  11.    double d;};  
  12.      
  13. cout<<sizeof(s1)<<endl; // 24  
  14. cout<<sizeof(s2)<<endl; // 16  
         占空间的最大成员是double类型变量,故对齐空间大小为8。s1中的c和d,s2中a,b,c可以放进一个“8”位空间中。

例子2

  1. struct s1  
  2. {char a[8];};  
  3.   
  4. struct s2  
  5. {double d;};  
  6.   
  7. struct s3{    
  8.   s1 s;  
  9.   char a;};  
  10.   
  11. struct s4{  
  12.   s2 s;  
  13.   char a; };  
  14.   
  15. cout<<sizeof(s1)<<endl; // 8  
  16. cout<<sizeof(s2)<<endl; // 8  
  17. cout<<sizeof(s3)<<endl; // 9  
  18. cout<<sizeof(s4)<<endl; // 16  
    虽然s1s2大小都是8,但是s1的对齐空间大小是1(char)s28double)所以定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。这里结构体中定义的数组可以当做多个同类数据顺序排列,以此确定对齐的空间大小。

例子3

  1. struct s1 {   
  2.  int i: 8;   
  3.  int j: 4;   
  4.  double b;   
  5.  int a:3;};   
  6.   
  7. struct s2 {   
  8.  int i;   
  9.  int j;   
  10.  double b;   
  11.  int a;};   
  12.   
  13. struct s3 {   
  14.  int i;   
  15.  int j;   
  16.  int a;   
  17.  double b;};   
  18.   
  19. struct s4 {   
  20.  int i: 8;   
  21.  int j: 4;   
  22.  int a:3;   
  23.  double b;};   
  24.   
  25. cout<<sizeof(s1)<<endl; // 24   
  26. cout<<sizeof(s2)<<endl; // 24   
  27. cout<<sizeof(s3)<<endl; // 24   
  28. cout<<sizeof(s4)<<endl; // 16   
       在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。double存在会干涉到位域。所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。
    如上。以double--8字节为单位,分配位,以s1为例。i,j占据一个double长度,b自己占据一个double长度,a占据另外一个double。
    注意:计算结构体嵌套结构体的内存空间时,注意嵌套之结构体的对齐空间非所占空间,而是两者的最大size变量。数组并不作为一个整体变量计算内存。

⑦基本操作结果

32位系统中

     sizeof  int:4
     sizeof  short:2
     sizeof  long:8
     sizeof  float:4
     sizeof  double:8
     sizeof  char:1
     sizeof  *p:4
     sizeof  WORD:2
     sizeof  DWORD:4

64位系统中:

    指针一律为8字节

    


2.其它

    如下:

class A{
	int i;
	union U{
		char buffer[13];
		int i;
	} u;
	typedef int* (*p)(int,int);
	enum{red,blue,white} e;
};

          sizeof(A)为 4+16+0+4=24。注意,union设计到内存对齐,并且以最大的存储单元计算空间,此时应为16。enum类型变量大小为4。这里应该注意的是,typedef只是定义了一个类型,并没有定义变量,因此不占内存空间。反之,倘若A存在成员指针,不管是什么类型的,大小都为4.

 

         倘若用#pragma pack(2)约束以两个字节对齐,则结果为22.因为此时枚举类型大小为14.









posted on 2015-07-01 11:30  攻城狮凌风  阅读(268)  评论(0编辑  收藏  举报

导航