一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

struct的內(nèi)存對齊(轉(zhuǎn))

 戴維圖書館 2013-12-17

結(jié)構(gòu)體的對齊

sizeof計算一個結(jié)構(gòu)體的大小時,經(jīng)常得到的值比結(jié)構(gòu)體內(nèi)部成員所占內(nèi)存總和要大,這就是因為在結(jié)構(gòu)體內(nèi)部,成員在存儲時有對齊的規(guī)則。結(jié)構(gòu)體對齊指的是 編譯器向結(jié)構(gòu)體插入無用內(nèi)存的能力,插入無用內(nèi)存使得結(jié)構(gòu)體成員以最佳方式對齊,從而得到更高的效能。當(dāng)基本數(shù)據(jù)類型以字節(jié)地址(幾倍于自身大?。┐鎯r,很多處理器能夠獲得最佳效能。

以下是幾個例子:

Struct x

{

Short s;//2 bytes and 2 padding tytes

Int i; //4 bytes

Char c; //1 bytes and 3 padding bytes

};

Struct y

{

Int i; //4 bytes

Char c ; //1 bytes and 1 padding byte

Short s; //2 bytes

};

Struct z

{

Int i; //4 bytes

Short s; // 2 bytes

Char c; //1 bytes and 1 padding byte

};

Sizeof(x)=12; sizeof(y)=8; sizeof(z)=8;

X的內(nèi)存布局: s I c

11** 1111 1***

Y的內(nèi)存布局: I c s

1111 1* 11

Z的內(nèi)存布局: I s c

1111 11 1*

其中*表示填充的字節(jié),xs后面為什么 要填充兩個 字節(jié)?因為i是整型,其起始位置要為4的倍數(shù)。C后面要填充3個字節(jié),因為結(jié)構(gòu)體size要為4(即最大類型 ——整型sizeof(int))的倍數(shù)。

YC后面填充一個 字節(jié),因為sshort類型,起始位置要為2的倍數(shù)。S后面沒有填充,因為cs正好占用 4個字節(jié)。

Zs后面沒有填充,因為sc正好占用4個字節(jié),c填充一個字節(jié) 因為struct大小要為int的整數(shù)倍。

再看一個有結(jié)構(gòu)體作為成員的例子:

Struct A

{

Int a;

Double b;

Float c;

};

Struct B

{

Char e[2];

Int f;

Double g;

Short h;

Struct A I;

};

Sizeof(A)=24; 因為 int4,double8,float4,總長為8 倍數(shù),補(bǔ)齊,所以為24。 Sizeof(B)=48;看一下B的布局

B的內(nèi)存布局:e f g h i

11** 1111 11111111 11****** 1111****, 11111111, 1111****

I其實就是A的內(nèi)存布局。I 起始位置要為24的倍數(shù),所以h后面要補(bǔ)齊(A的最大類型是double,占8個字節(jié),所以i開始要8字節(jié)對齊,即8的倍數(shù),所以h要填充)。

通過把最大的數(shù)據(jù)類型放在結(jié)構(gòu)體的開始,最小數(shù)據(jù)類型放在結(jié)構(gòu)體的最后,這樣可以得到最小的結(jié)構(gòu)體size

通過上面的例子可以總結(jié)一下三個規(guī)律:

1 數(shù)據(jù)成員對齊,結(jié)構(gòu)體(或聯(lián)合體)的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在offset0的地方,以后每個數(shù)據(jù)成員存儲的起始位置要從該成員大小的整數(shù)倍開始(比如int32位機(jī)為4字節(jié),則要從4的整數(shù)倍地址開始存儲)。

2 結(jié)構(gòu)體作為成員,如果 一個 結(jié)構(gòu)體里面有某些結(jié)構(gòu)體成員,則結(jié)構(gòu)體成員要從其內(nèi)部最大元素大小的整數(shù)倍地址開始存儲(struct b里面有struct a,a里面有char,int,double等元素,那么a應(yīng)該從8的整數(shù)倍開始存儲)。

3 結(jié)構(gòu)體的總大小,也就是sizeof的結(jié)果,必須是其內(nèi)部最大成員的整數(shù)倍,不足的要補(bǔ)齊。

還有一種常見情況,結(jié)構(gòu)體中含有位域字段。位域成員不能單獨被取sizeof值。規(guī)定int,unsigned int bool可以作為位域類型,但編譯器幾乎都對此作了擴(kuò)展,允許其他類型的存在。使用位于的主要目的是壓縮存儲,其大致規(guī)則:

1 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的 字段將緊鄰前一個字段存儲,知道不能容納為止;

2 如果相鄰字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數(shù)倍;

3 如果相鄰的位域字段的類型 不同,則各編譯器的 具體實現(xiàn)有差異,VC6采取不壓縮方式,Dev-C++采取壓縮方式;

4 如果位域字段之間穿插著非位域字段,則不進(jìn)行壓縮。

5 整個結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。

看下面例子:

struct A{

short f1:3;

short f2:4;

short f3:10;

}; A的布局為 f 1 f2 f3

111 1111*** **(11*) 1—1(101)**(6*) 位域類型為short,第一個字節(jié)能容納f1f2,所以f2被壓縮到第1個字節(jié)中,而f3只能從下一個字節(jié)開始。因此sizeof(A)=2。

Struct B{

Char f1:3;

Short f2:4;

Char f3:5;

};相鄰位域的類型不同,在VC6sizeof6,在Dev-C++中為2.

Struct C{

Char f1:3;

Char f2;

Char f3:5;

};非位域字段插在其中,不會產(chǎn)生壓縮,大小為3。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    91超频在线视频中文字幕| 视频在线观看色一区二区| 精品精品国产欧美在线| 91午夜少妇极品福利| 字幕日本欧美一区二区| 国产成人亚洲综合色就色| 国产三级欧美三级日韩三级| 亚洲欧美天堂精品在线| 国产精品国三级国产专不卡| 亚洲国产一区精品一区二区三区色| 五月天丁香亚洲综合网| 亚洲av秘片一区二区三区| 欧美国产日本免费不卡| 四季av一区二区播放| 欧美精品久久男人的天堂| 美日韩一区二区精品系列| 午夜精品在线观看视频午夜| 国产成人综合亚洲欧美日韩| 亚洲国产av在线视频| 在线播放欧美精品一区| 日韩成人高清免费在线| 老司机精品一区二区三区| 99久久国产亚洲综合精品| 国产毛片对白精品看片| 欧美日韩国产精品自在自线| 99福利一区二区视频| 亚洲国产精品久久综合网| 五月情婷婷综合激情综合狠狠| 黄片免费观看一区二区| 欧美不卡高清一区二区三区| 99久久免费看国产精品| 高中女厕偷拍一区二区三区 | 亚洲伦片免费偷拍一区| 国产亚洲欧美日韩精品一区 | 精品精品国产自在久久高清| 大屁股肥臀熟女一区二区视频| 亚洲免费黄色高清在线观看| 亚洲第一视频少妇人妻系列 | 日本人妻的诱惑在线观看| 日韩成人中文字幕在线一区 | 免费大片黄在线观看日本|