門戶網(wǎng)站建設(shè)審批程序網(wǎng)絡(luò)營(yíng)銷的方法包括哪些
什么是字節(jié)對(duì)齊
1.空類
class A
{}
對(duì)空類做sizeof()計(jì)算時(shí)應(yīng)當(dāng)?shù)扔?
2.帶虛函數(shù)的類
如果有一個(gè)類,包含兩個(gè)32位整型的數(shù)據(jù)成員,一個(gè)普通成員函數(shù),還有一個(gè)virtual虛函數(shù),在32位機(jī)器上,這個(gè)類sizeof()計(jì)算的時(shí)候得到多少,編譯是4字節(jié)對(duì)齊
32位機(jī)器
#pragma pack(4)
class K
{
public:int a;int b;void fun(); virtual void fun1();
};
#pragma pack()
a占4個(gè)字節(jié)
b占4個(gè)字節(jié)
void fun不占用內(nèi)存
因?yàn)橛幸粋€(gè)virtual虛寒函數(shù),有一個(gè)虛函數(shù)指針,32系統(tǒng)中占用4個(gè)字節(jié)
所以,占用12個(gè)字節(jié)。
- 如果變成8字節(jié)對(duì)齊呢,應(yīng)該是多大?
#pragma pack(8)
class K
{
public:int a;int b;void fun(); virtual void fun1();
};
#pragma pack()
也許你會(huì)覺得是16,但是正確的結(jié)果是12.
為什么依然還是12呢?
因?yàn)樽止?jié)對(duì)齊的規(guī)則規(guī)定,
對(duì)于結(jié)構(gòu)體,他的有效對(duì)齊值,是#pragma pack()和該結(jié)構(gòu)體中最大數(shù)據(jù)成員兩者中的較小的那個(gè)值。
這里#pragma pack(8)值為8,但K class中最大數(shù)據(jù)成員為4個(gè)字節(jié),所類K依然按照4字節(jié)對(duì)齊。
- 如果一個(gè)成員函數(shù)變成2個(gè)成員函數(shù)呢?
#pragma pack(8)
class K
{
public:int a;int b;void fun(); void fun2();virtual void fun1();
};
#pragma pack()
sizeof(K)依然是占用12個(gè)字節(jié)。
因?yàn)槌蓡T函數(shù)不占用類對(duì)象的內(nèi)存的。
- 如果增加一個(gè)虛函數(shù),變成兩個(gè)虛函數(shù)了呢?
#pragma pack(8)
class K
{
public:int a;int b;void fun(); void fun2();virtual void fun1();virtual int fun3();
};
#pragma pack()
sizeof(K)依然是占用12個(gè)字節(jié)。
因?yàn)槊總€(gè)類只維護(hù)一個(gè)虛函數(shù)指針,所有的虛函數(shù)都放在虛函數(shù)表中呢。
32位系統(tǒng)中,指針占用4個(gè)內(nèi)存。
- 再增加一個(gè)char類型,大小會(huì)變成多少?
#pragma pack(8)
class K
{
public:int a;int b;char c;void fun(); void fun2();virtual void fun1();virtual int fun3();
};
#pragma pack()
答案是:16字節(jié)
雖然,#pragma pack為8,但K類最大數(shù)據(jù)成員大小占4個(gè)字節(jié),
所以K類按照4字節(jié)對(duì)齊。
a占4個(gè)字節(jié)0-3
b占4個(gè)字節(jié)4-7
c占一個(gè)字節(jié),8-11
虛函數(shù)表指針,必須從4的倍數(shù)開頭,12-15
64位機(jī)器
#pragma pack(4)
class K
{
public:int a;int b;void fun(); virtual void fun1();
};
#pragma pack()
答案是:16字節(jié)
因?yàn)?4位機(jī)器下,虛函數(shù)表指針為8個(gè)字節(jié)
- 如果增加一個(gè)char 變量
#pragma pack(4)
class K
{
public:int a;int b;char c;void fun(); virtual void fun1();
};
#pragma pack()
答案是:20個(gè)字節(jié),因?yàn)橛行?duì)齊值為4,
地址編號(hào) | 0 | 1 | 2 | 3 |
---|---|---|---|---|
a | a | a | a | |
地址編號(hào) | 4 | 5 | 6 | 7 |
b | b | b | b | |
地址編號(hào) | 8 | 9 | 10 | 11 |
c | ||||
地址編號(hào) | 12 | 13 | 14 | 15 |
vptr | vptr | vptr | vptr | |
地址編號(hào) | 16 | 17 | 18 | 19 |
vptr | vptr | vptr | vptr |
- 如果編譯改成8字節(jié)對(duì)齊呢
#pragma pack(8)
class K
{
public:int a;int b;char c;void fun(); virtual void fun1();
};
#pragma pack()
答案是:24個(gè)字節(jié)
因?yàn)?字節(jié)對(duì)齊,vptr需要從8的倍數(shù)開始存儲(chǔ)。
地址編號(hào) | 0 | 1 | 2 | 3 |
---|---|---|---|---|
a | a | a | a | |
地址編號(hào) | 4 | 5 | 6 | 7 |
b | b | b | b | |
地址編號(hào) | 8 | 9 | 10 | 11 |
c | ||||
地址編號(hào) | 12 | 13 | 14 | 15 |
地址編號(hào) | 16 | 17 | 18 | 19 |
vptr | vptr | vptr | vptr | |
地址編號(hào) | 20 | 21 | 22 | 23 |
vptr | vptr | vptr | vptr |