• C++ sizeof总结


    关键字sizeof的作用是返回对象或类型占用的内存字节数,返回值是size_t。

    基本数据类型占用的字节数:(32位系统)

    char 1字节

    bool 1字节

    short 2字节

    int 4字节

    long 4字节

    float 4字节

    double 8字节

        对sizeof结果的一个重要影响因素是字节对齐。首先看一个公式:有效对齐值=min(自身对齐值,设置对齐值)。

    自身对齐值是一个数据类型自身所占字节数,

        例子:

    int a;  //自身对齐值是4
    char c;  //自身对齐值是1
    double d;  //自身对齐值是8
    
    //对于结构体,自身对齐值是其内置数据类型中对齐值最大的值
    struct s1{
        int q;    //4
        bool e;    //1
        char w;   //1
    };// 最大的是int q,所以自身对齐值是4
    
    struct s2{
        int q;    //4
        bool e;    //1
        double r;   //8
    };// 最大的是double r,所以自身对齐值是8

    设置对齐值是编译器默认的对齐值,笔者用的是vs2013,默认对齐值是4字节,可以Project--->Properties--->Configuration Properties--->CC++--->Code Generation

    --->Struct Member Alignment中设置,也可以通过宏#pragma pack(n)来设置,n为要设置的对齐字节。

        有效对齐值是对象或类型的自身对齐值和设置对齐值中较小的一个,也是实际真正的对齐值。

        在上面的例子上加点改动后:

    #pragma pack(4) //设置对齐值为4
    struct s1{
    int  q;
    bool e;
    char w;
    }; //s1的自身对齐值是4,所以s1的有效对齐值=min(4,4)=4
    
    #pragma pack(2) //设置对齐值为2
    struct s2{
    int q;
    bool e;
    double r;
    }; //s2的自身对齐值是8,所以s2的有效对齐值=min(8,2)=2

    知道了有效对齐值就可以轻松地计算sizeof了。

    一、基本数据类型的sizeof

         sizeof(int)=4

         sizeof(double)=8

         ......

    二、结构体的sizeof

    #pragma pack(4)
    struct s1{
    int a;
    char b;
    };  //有效对齐值是4
    sizeof(s1)=8 
    //int a占4字节,储存在0x00--0x03,char b占1字节,储存在0x04,因为有效对齐值是4,所以char b后面的0x05--0x07补齐对齐,一共占用8字节
    
    //把s1稍作改动
    struct s1{
    char b;
    int a;
    }; //有效对齐值是4
    sizeof(s1)=8
    //答案一样,但是内部储存情况变了。char b占1字节,储存在0x00,int a占4字节,因为有效对齐值是4,0x01---0x03只剩3字节的内存,小于int a所需的字节数,所以新分配一段4字节(有效对齐值)内存,最终int a储存在0x04---0x07
    
    //再看一个例子
    struct s2
    {
    char a;
    short b;
    double c;
    char d;
    }; //有效对齐值是4
    sizeof(s2)=16
    //char a占1字节,储存在0x00;short b占2字节,由于有效对齐值是4,第一段内存剩余3字节0x01---0x03,大于short b所需,所以short b储存在0x02---0x03(注意:储存首地址必须是成员大小的整数倍,所以0x01空出);double c占8字节,大于有效对齐值,所以分配两段内存0x04---0x0B用于储存double c;char d占1字节,储存在0x0C,按有效对齐值4字节对齐,最后的0x0D---0x0F补齐对齐。一共16字节。

    三、结构体中含有结构体类型的sizeof

    结构体的自身对齐值是其内置类型中最大的一个。

    例子:

    #pragma pack(2)
    class A
    {
    public:
        int a;
        double s;
        
    }; //A的自身对齐值是double s的自身对齐值,为8
        //但A的有效对齐值是min(8,2)=2,sizeof(A)=12
    class B
    {
    public:
        char c; //自身对齐值1,占1字节
        A b; //自身对齐值8,占sizeof(A)=12字节
    }; //B的自身对齐值等于A的自身对齐值,为8
        //B的有效对齐值=min(8,2)=2,按2字节对齐
    sizeof(B)=14 
    //char c占1字节,储存在0x00,0x01空出;A b占12字节。一共14字节。

    四、结构体中含有虚函数的sizeof

    带有虚函数的结构体会有一个虚表指针,占4字节大小。

    例子:

    #pragma pack(4)
    Class A
    {
     public:
         int a;
         virtual int test();
    };
    sizeof(A)=8  //int a占4字节,虚表指针占4字节,一共8字节。
                        //注意:如果一个结构体有多个虚函数,也还是只有一个虚表指针,即多个虚函数共用一个虚表指针

    对于继承的情况,如果基类有虚函数,那么这个虚表指针也会被继承下来,即基类和派生类共用一个虚表指针。

    例子:

    #pragma pack(4)
    class A
    {
    public:
        int a;
        double s;
        virtual int test();
    };
    class B:public A
    {
    public:
        virtual int test_1(); //共用基类虚表指针
            virtual int test_2(); //共用基类虚表指针
        char c;
        
    };
    sizeof(B)=20  
    //int a占4字节+double s占8字节+虚表指针占4字节+char c占1字节+3字节补齐对齐=20字节

    五、联合体的sizeof

    联合体中各成员共享内存,整个联合体的sizeof就是每个成员sizeof的最大值。

    例子:

    union u  
    {  
        int a;    
        double b;  
        char c;
        bool d;
    };  
    sizeof(u)=sizeof(b)=8

    六、含有static的结构体的sizeof

    static和全局变量都是储存在静态存储区,计算结构体的sizeof时只计算非static成员。

    例子:

    #pragma pack(4)
    class A
    {
    public:
        int a;
        double b;
        static int d; //不管他
        
    };
    sizeof(A)=12  //int a占4字节+double b占8字节=12

    七、函数的sizeof

    结果是函数返回类型的大小,所以不能对没有返回值的函数求sizeof。

    格式sizeof(函数名(实参表))

    例子:

    int A()
    {
          return 1;
    }
    sizeof(A())=sizeof(int)=4
    
    char B(char b)
    {
         return b;
    }
    sizeof(B('b'))=sizeof(char)=1
    
    void C()
    {
    }
    sizeof(C()) //error,因为没有返回类型

    有理解错误的地方希望各位大神指正啊!!感激不尽!

  • 相关阅读:
    ubantu安装pip3
    ubantu更换镜像源
    git 快速上手
    python zmq(ZeorMQ)
    用python连接SQL server数据库
    Django模板url需要注意的地方
    希尔排序记录--最好写的排序
    口腔溃疡要对症-------阴虚火旺和阳虚火旺
    与大学室友,保持一定的距离
    取指 间址 执行 中断 FE IND EX INT四个触发器
  • 原文地址:https://www.cnblogs.com/zjc0202/p/4409939.html
Copyright © 2020-2023  润新知