歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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--->C\C++--->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,因為沒有返回類型

有理解錯誤的地方希望各位大神指正啊!!感激不盡!

Copyright © Linux教程網 All Rights Reserved