国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

結(jié)構(gòu)體、聯(lián)合體和位斷的內(nèi)存對(duì)齊問(wèn)題

2019-11-10 16:52:55
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

內(nèi)存對(duì)齊的原因:

1.平臺(tái)原因

   不是所有硬件平臺(tái)都可以訪問(wèn)任意地址上的任意數(shù)據(jù);

   某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。

2.性能原因

  數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能的在自然邊界上對(duì)齊。

  原因在于在訪問(wèn)未對(duì)齊的內(nèi)存時(shí),處理器需要進(jìn)行兩次內(nèi)存訪問(wèn);而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次。

 

結(jié)構(gòu)體(struct)內(nèi)存對(duì)齊規(guī)則:

1.第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。

2.其它成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。

   //對(duì)齊數(shù)=編譯器默認(rèn)的一個(gè)對(duì)齊數(shù)與該成員大小的一個(gè)較小值

   Vs中默認(rèn)的對(duì)齊數(shù)是8

   linux中默認(rèn)的對(duì)齊數(shù)是4

3結(jié)構(gòu)體總大小:最大對(duì)齊數(shù)每個(gè)成員變量的除了第一個(gè)成員都有一個(gè)對(duì)對(duì)齊數(shù))的整數(shù)倍。每個(gè)成員變量在對(duì)    齊之后,把成員大小加起來(lái),再擴(kuò)大到最大對(duì)齊數(shù)的整數(shù)倍

4.如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有對(duì)齊數(shù)  (含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。

 

 

聯(lián)合體(union)的內(nèi)存對(duì)齊規(guī)則

1.聯(lián)合體也是一個(gè)結(jié)構(gòu),聯(lián)和體是共享內(nèi)存的。

2.所以的聯(lián)合體的內(nèi)部成員起始地址都是一樣的,都是聯(lián)合體的首地址。

3.它的對(duì)齊方式要適應(yīng)所有成員。

4.該空間必須足夠容納最寬成員。

5.聯(lián)合體的對(duì)齊數(shù)為最大成員的對(duì)齊數(shù)。

 

 

位斷(struct)的內(nèi)存對(duì)齊規(guī)則:

1.如果相鄰位域字段的類型相同,且其位寬之和小于sizeof(type)的大小,則后面的字段緊鄰前一個(gè)字節(jié)存儲(chǔ),直到  容納不下為止;基本成員是連續(xù)存儲(chǔ)的,若這個(gè)單元空間放不下下一個(gè)成員,則新開辟一個(gè)單元空間,這樣可以節(jié)  省內(nèi)存空間。

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

3.如果相鄰位域字段的類型不相同,則各編譯器的實(shí)現(xiàn)有差異,vc6采取不壓縮方式,Dev-c++采取壓縮。

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

5.結(jié)構(gòu)體的總大小為最大對(duì)齊數(shù)的整數(shù)倍。因?yàn)槲粩喑蓡T必須聲明為int、signed int或unsigned int類型,因此結(jié)構(gòu)體的  大小都是4的整數(shù)倍。

 

 

下面我們看一個(gè)代碼,通過(guò)以上規(guī)則計(jì)算其大小結(jié)構(gòu)體,位斷,聯(lián)合體的大小:

    在計(jì)算之前,我們首先需要明確的是各個(gè)數(shù)據(jù)成員的對(duì)齊模數(shù),對(duì)齊模數(shù)和數(shù)據(jù)成員本身的長(zhǎng)度以及PRagma pack()編譯參數(shù)有關(guān),#pragma  pack(n) 可以設(shè)定對(duì)對(duì)齊數(shù),編譯器支持往比默認(rèn)對(duì)齊數(shù)小的數(shù)調(diào)。對(duì)齊數(shù)=編譯器默認(rèn)的一個(gè)對(duì)齊數(shù)與該成員大小的一個(gè)較小值。如果程序沒有明確指出,就需要知道編譯器默認(rèn)的對(duì)齊模數(shù)值。

下表是Windows xp/DEV-C++Linux/GCC中基本數(shù)據(jù)類型的長(zhǎng)度和默認(rèn)對(duì)齊模數(shù)。 

 

 

char

short

int

long

float

double

long long

long double

Win-32

長(zhǎng)度

1

2

4

4

4

8

8

8

模數(shù)

1

2

4

4

4

8

8

8

Linux-32

長(zhǎng)度

1

2

4

4

4

8

8

12

模數(shù)

1

2

4

4

4

4

4

4

Linux-64

長(zhǎng)度

1

2

4

8

4

8

8

16

模數(shù)

1

2

4

8

4

8

8

16

#include<stdio.h>#include<windows.h>#pragma pack(4)    //默認(rèn)對(duì)齊數(shù)為4struct A{	char a1;    //1+3  char占1個(gè)字節(jié),double要對(duì)齊到4的整數(shù)倍處,所以1+3對(duì)其到4	double a2;  //8	int a3;     //4};             //結(jié)構(gòu)體總大小:16   對(duì)齊數(shù):4union un{	char b1;     //1	struct A b2; //16	int b3;      //4};             //聯(lián)合體總大小:16   對(duì)齊數(shù)為:4(最大成員的對(duì)齊數(shù))struct B{	unsigned int c1 : 4;            //4	unsigned int c2 : 31; //位域    //4	unsigned int c3 ;    //非位域   //4	unsigned int c4 : 1;            //4};              //位斷的總大小:16   對(duì)齊數(shù):4 struct obj{	double d1;     //8	char d2;       //1+3	union un d3;   //16 使1+3對(duì)齊到12,即4的整數(shù)倍	struct B d4;   //16	char d5;       //1+3 使1+3對(duì)齊到48,即4的整數(shù)倍	struct C{		struct B e1;//16		char e2;    //1+3 使1+3對(duì)齊到20,即4的整數(shù)倍		double e3;  //8	};           //總大小:28   對(duì)齊數(shù):4	char d6;     //1+3};               //結(jié)構(gòu)體obj的總大小:80(使1+3對(duì)齊到80,即4的整數(shù)倍)  最大對(duì)齊數(shù):4int main(){	printf("%d/n", sizeof(struct obj));  //結(jié)構(gòu)體obj的總大小:80	system("pause");	return 0;}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 房产| 贵溪市| 太康县| 宜君县| 滦平县| 湾仔区| 同心县| 六盘水市| 宁津县| 伊吾县| 寿宁县| 金阳县| 吉木萨尔县| 什邡市| 万源市| 东乌珠穆沁旗| 交口县| 无棣县| 东城区| 太白县| 禹城市| 疏附县| 电白县| 公主岭市| 河间市| 南城县| 墨竹工卡县| 遂平县| 夏邑县| 天气| 柏乡县| 营口市| 海门市| 乌拉特中旗| 靖江市| 平陆县| 宁安市| 淳安县| 隆德县| 阜平县| 漯河市|