青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

字節對齊(強制對齊以及自然對齊)

轉載自:http://www.cnblogs.com/alfredzzj/archive/2012/06/17/2552431.html

struct {}node;

32為的x86,window下VC下sizeof(node)的值為1,而linux的gcc下值為0;


一、WINDOWS下(VC--其實GCC和其原理基本一樣,象這種問題,一般要查具體的編譯器設置)字節對齊的規則:

1、一般設置的對齊方式為1,2,4字節對齊方式,VC一般默認為4字節(最大為8字節)。結構的首地址必須是結構內最寬類型的整數倍地址;另外,結構體的每一個成員起始地址必須是自身類型大小的整數倍(需要特別注意的是windows下是這樣的,但在linux的gcc編譯器下最高為4字節對齊),否則在前一類型后補0;這里特別提到的是數組一定要注意,而且在一些編程的技巧中,我們可以使用數組強制字節達到對齊的目的。這在網絡編程中是很常見的。

舉例:比如CHAR型占用空間為1字節,則其起始位置必須可被1整除。INT為4字節,其起始位置必須被4帶隊,依次類推。(我們假定類或結構體的起始位置為0位置,其實編譯器是在開辟空間時,會尋找起始位置可被結構內最寬類型整除的地址做為開始地址,因此我們可以假定其為0值,因為這0值可以被任意的類型整除。)

2、結構體的整體大小必須可被對齊值整除,默認4(默認,且結構中的類型大小都小于默認的4)。

3、結構體的整體大小必須可被本結構內的最寬類型整除。(其實和上一條是一樣的,但這里獨立出來,起注意作用。比如結構體里的有DOUBLE,那么結構的大小最后必須可被8整除)

注意:GCC不是這樣,就是最高只能被4整除,它是個死的。

否則(2、3條),編譯器會在結構的最后添充一定的特定字符來補齊。

struct T 
{ 
char ch; 
double d ; 
};

在VC中是16個字節,GCC中為12個字節。

4、對于結構體內嵌套結構體的形勢,規定是必須按照基本數據類型來定義,而不能以嵌套結構大小來做為上三種使用的基準。

二、舉例:

struct A 
{ 
int a; 
char b; 
short c; 
}; 
struct B 
{ 
char b; 
int a; 
short c; 
}; 
struct C 
{ 
double t; 
char b; 
int a; 
short c; 
}; 
struct D 
{ 
char b; 
double t; 
int a; 
short c; 
};

在VC中,SIZEOF這四個結構體,分別為:8、12、24、24;

我們先談第一個,(說明一下,在考慮結構體大小時,我們基本可以忽略起始地址的問題,因為這個編譯器會自動為我們做好,見上面的說明),結構體內首先是一個INT的4字節,起始地址假定為0,整除4,其小于等于默認的4字節對齊且0為4(INT的占用空間)的整數倍,所以,其占四個字節;其后為起始地址為5,空間為1個字節的CHAR,小于4且5為1(CHAR占用空間)的整數倍,故占用1個字節,然后是一個起始地址為5占2個字節的SHORT,其小于4,但5不為2位數,故補齊一個字節,從第6個字節開始,占2字節空間。所以共占用4+1+1(補)+2=8;8/4=2;整除,故占用8字節空間。

再談第2個,CHAR不用解釋,占有一個字節空間,且可以被0地址整除。而INT則占4字節空間,所以其必須在CHAR后補齊3字節,到第四個字節,才是INT的真正地址。SHORT也不用說,所以共占有:1+3(補)+4+2=10個字節,但10不能整除4,所以要在結構體最后補齊2字節。故實際占有10+2= 12個字節。

談第三個,C結構體只是在B結構體前加了一個DOUBLE,其它都一樣,按說應該是20個字節啊,但注意我們上面規則的第3條。必須是最寬類型的整數倍,一定要分清,所以得補齊到24,D結構體類似,不再講。

三、結構體的中含有位域

這個東西用得比較少,但還是總結一下:

如果結構體中含有位域(bit-field),那么VC中準則又要有所更改: 
1) 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止; 
2) 如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍; 
3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現有差異,VC6采取不壓縮方式(不同位域字段存放在不同的位域類型字節中),Dev-C++和GCC都采取壓縮方式; 
備注:當兩字段類型不一樣的時候,對于不壓縮方式,例如:

struct N 
{ 
char c:2; 
int i:4; 
};

依然要滿足不含位域結構體內存對齊準則第2條,i成員相對于結構體首地址的偏移應該是4的整數倍,所以c成員后要填充3個字節,然后再開辟4個字節的空間作為int型,其中4位用來存放i,所以上面結構體在VC中所占空間為8個字節;而對于采用壓縮方式的編譯器來說,遵循不含位域結構體內存對齊準則第2條,不同的是,如果填充的3個字節能容納后面成員的位,則壓縮到填充字節中,不能容納,則要單獨開辟空間,所以上面結構體N在GCC或者Dev-C++中所占空間應該是4個字節。

4) 如果位域字段之間穿插著非位域字段,則不進行壓縮; 
備注: 
結構

typedef struct 
{ 
char c:2; 
double i; 
int c2:4; 
}N3;

在GCC下占據的空間為16字節,在VC下占據的空間應該是24個字節。

四、字節對齊的控制方法

主要是使用:

#pragma pack (2) /*指定按2字節對齊*/ 
struct C 
{ 
char b; 
int a; 
short c; 
}; 
#pragma pack () /*取消指定對齊,恢復缺省對齊*/

大家如果有興趣,可以自己上機調一下各種對齊方式下的占用空間大小,這里就不再舉例。

#pragma pack(push) //保存對齊狀態 
#pragma pack(4)//設定為4字節對齊 
struct test 
{ 
char m1; 
double m4; 
int m3; 
}; 
#pragma pack(pop)//恢復對齊狀態

這里需要注意的是,如果對齊的字節非為1、2、4、8等可整除位數,則自動默認回默認的對齊字節數,這個我沒有測試,大家可以試一下,應該沒什么問題。

五、多編譯器的使用:(其下為轉載

為了防止不同編譯器對齊不一樣,建議在代碼里面指定對齊參數

可能重要的一點是關于緊縮結構的。緊縮結構的用途 其實最常用的結構對齊選項就是:默認對齊和緊縮。在兩個程序,或者兩個平臺之間傳遞數據時,我們通常會將數據結構設置為緊縮的。這樣不僅可以減小通信量,還可以避免對齊帶來的麻煩。假設甲乙雙方進行跨平臺通信,甲方使用了“/Zp2”這么奇怪的對齊選項,而乙方的編譯器不支持這種對齊方式,那么乙方就可以理解什么叫欲哭無淚了。 當我們需要一個字節一個字節訪問結構數據時,我們通常都會希望結構是緊縮的,這樣就不必考慮哪個字節是填充字節了。我們把數據保存到非易失設備時,通常也會采用緊縮結構,既減小存儲量,也方便其它程序讀出。各編譯器都支持結構的緊縮,即連續排列結構的各成員變量,各成員變量之間沒有任何填充字節。這時,結構的大小等于各成員變量大小的和。緊縮結構的變量可以放在1n邊界,即任意地址邊界。在GNU gcc:

typedef struct St2Tag

{

St1 st1;

char ch2;

}

__attribute__ ((packed)) St2;

在ARMCC:

typedef __packed struct St2Tag

{

St1 st1;

char ch2;

} St2;

在VC:

#pragma pack(1)

typedef struct St2Tag

{

St1 st1;

char ch2;

} St2;

#pragma pack()

針對不同的編譯器:

#ifdef __GNUC__

#define GNUC_PACKED __attribute__ ((packed))

#else

#define GNUC_PACKED

#endif

#ifdef __arm

#define ARM_PACKED __packed

#else

#define ARM_PACKED

#endif

#ifdef WIN32

#pragma pack(1)

#endif

typedef ARM_PACKED struct St2Tag

{

St1 st1;

char ch2;

}

GNUC_PACKED St2;

#ifdef WIN32

#pragma pack()

#endif

最后記錄一個小細節。gcc編譯器和VC編譯器都支持在緊縮結構中包含非緊縮結構,例如前面例子中的St2可以包含非緊縮的St1。但對于ARM編譯器而言,緊縮結構包含的其它結構必須是緊縮的。如果緊縮的St2包含了非緊縮的St1,編譯時就會報錯:

 

 

 

 

C語言的字節對齊及#pragma pack的使用

2010-04-16 09:44:33| 分類: vc/c/c++ | 標簽: |字號大中小 訂閱

C編譯器的缺省字節對齊方式(自然對界)

在缺省情況下,C編譯器為每一個變量或是數據單元按其自然對界條件分配空間。

在結構中,編譯器為結構的每個成員按其自然對界(alignment)條件分配空間。各個成員按照它們被聲明的順序在內存中順序存儲(成員之間可能有插入的空字節),第一個成員的地址和整個結構的地址相同。

C編譯器缺省的結構成員自然對界條件為“N字節對齊”,N即該成員數據類型的長度。如int型成員的自然對界條件為4字節對齊,而double類型的結構成員的自然對界條件為8字節對齊。若該成員的起始偏移不位于該成員的“默認自然對界條件”上,則在前一個節面后面添加適當個數的空字節。

C編譯器缺省的結構整體的自然對界條件為:該結構所有成員中要求的最大自然對界條件。若結構體各成員長度之和不為“結構整體自然對界條件的整數倍,則在最后一個成員后填充空字節。

例子1(分析結構各成員的默認字節對界條界條件和結構整體的默認字節對界條件):

struct Test
{
char x1; // 成員x1為char型(其起始地址必須1字節對界),其偏移地址為0

char x2; // 成員x2為char型(其起始地址必須1字節對界,其偏移地址為1

float x3; // 成員x3為float型(其起始地址必須4字節對界),編譯器在x2和x3之間填充了兩個空字節,其偏移地址為4

char x4; // 成員x4為char型(其起始地址必須1字節對界),其偏移地址為8
};

因為Test結構體中,最大的成員為flaot x3,因些此結構體的自然對界條件為4字節對齊。則結構體長度就為12字節,內存布局為1100 1111 1000。

例子2:

#include <stdio.h>
//#pragma pack(2)
typedef struct
{
int aa1; //4個字節對齊 1111
char bb1;//1個字節對齊 1
short cc1;//2個字節對齊 011
char dd1; //1個字節對齊 1
} testlength1;
int length1 = sizeof(testlength1); //4個字節對齊,占用字節1111 1011 1000,length = 12

typedef struct
{
char bb2;//1個字節對齊 1
int aa2; //4個字節對齊 01111
short cc2;//2個字節對齊 11
char dd2; //1個字節對齊 1
} testlength2;
int length2 = sizeof(testlength2); //4個字節對齊,占用字節1011 1111 1000,length = 12


typedef struct
{
char bb3; //1個字節對齊 1
char dd3; //1個字節對齊 1
int aa3; //4個字節對齊 001111
short cc23//2個字節對齊 11

} testlength3;
int length3 = sizeof(testlength3); //4個字節對齊,占用字節1100 1111 1100,length = 12


typedef struct
{
char bb4; //1個字節對齊 1
char dd4; //1個字節對齊 1
short cc4;//2個字節對齊 11
int aa4; //4個字節對齊 1111
} testlength4;
int length4 = sizeof(testlength4); //4個字節對齊,占用字節1111 1111,length = 8


int main(void)
{
printf("length1 = %d.\n",length1);
printf("length2 = %d.\n",length2);
printf("length3 = %d.\n",length3);
printf("length4 = %d.\n",length4);
return 0;
}

改變缺省的對界條件(指定對界) 
· 使用偽指令#pragma pack (n),C編譯器將按照n個字節對齊。 
· 使用偽指令#pragma pack (),取消自定義字節對齊方式。

這時,對齊規則為:

1、數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在offset為0的地方,以后每個數據成員的對齊按照#pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。

2、結構(或聯合)的整體對齊規則:在數據成員完成各自對齊之后,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大數據成員長度中,比較小的那個進行。

結合1、2推斷:當#pragma pack的n值等于或超過所有數據成員長度的時候,這個n值的大小將不產生任何效果。

因此,當使用偽指令#pragma pack (2)時,Test結構體的大小為8,內存布局為11 11 11 10。

需要注意一點,當結構體中包含一個子結構體時,子結構中的成員按照#pragma pack指定的數值和子結構最大數據成員長度中,比較小的那個進行進行對齊。例子如下:

#pragma pack(8) 
struct s1{ 
short a; 
long b; 
};

struct s2{ 
char c; 
s1 d; 
long long e; 
}; 
#pragma pack()

sizeof(s2)的結果為24。S1的內存布局為1100 1111,S2的內存布局為1000 1100 1111 0000 1111 1111。

例子:

#include <stdio.h>
#pragma pack(2)
typedef struct
{
int aa1; //2個字節對齊 1111
char bb1;//1個字節對齊 1
short cc1;//2個字節對齊 011
char dd1; //1個字節對齊 1
} testlength1;
int length1 = sizeof(testlength1); //2個字節對齊,占用字節11 11 10 11 10,length = 10

typedef struct
{
char bb2;//1個字節對齊 1
int aa2; //2個字節對齊 01111
short cc2;//2個字節對齊 11
char dd2; //1個字節對齊 1
} testlength2;
int length2 = sizeof(testlength2); //2個字節對齊,占用字節10 11 11 11 10,length = 10


typedef struct
{
char bb3; //1個字節對齊 1
char dd3; //1個字節對齊 1
int aa3; //2個字節對齊 11 11
short cc23//2個字節對齊 11

} testlength3;
int length3 = sizeof(testlength3); //2個字節對齊,占用字節11 11 11 11,length = 8


typedef struct
{
char bb4; //1個字節對齊 1
char dd4; //1個字節對齊 1
short cc4;//2個字節對齊 11
int aa4; //2個字節對齊 11 11
} testlength4;
int length4 = sizeof(testlength4); //2個字節對齊,占用字節11 11 11 11,length = 8


int main(void)
{
printf("length1 = %d.\n",length1);
printf("length2 = %d.\n",length2);
printf("length3 = %d.\n",length3);
printf("length4 = %d.\n",length4);
return 0;
}

另外,還有如下的一種方式:

· __attribute((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大于n,則按照最大成員的長度來對齊。

· __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊。

以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。


posted on 2014-04-17 15:43 楊粼波 閱讀(1047) 評論(0)  編輯 收藏 引用 所屬分類: C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情国产高清| 欧美日韩国产一级| 欧美成人免费大片| 欧美chengren| 亚洲二区视频| 欧美激情视频网站| 日韩性生活视频| 亚洲欧美国产高清va在线播| 欧美在线精品免播放器视频| 久久综合狠狠| 亚洲自拍偷拍一区| 国产精品av久久久久久麻豆网| 欧美日韩福利在线观看| 国产精品美女久久久久久2018| 国产欧美一区二区精品仙草咪| 国产亚洲欧美日韩在线一区| 亚洲国产精品久久久久秋霞蜜臀 | 亚洲国产另类久久精品| 亚洲激情综合| 午夜日韩电影| 欧美美女操人视频| 国内精品视频久久| 日韩网站在线看片你懂的| 欧美一级免费视频| 亚洲高清视频在线观看| 亚洲一区亚洲二区| 欧美国产免费| 韩国女主播一区| 亚洲桃色在线一区| 欧美国产日韩亚洲一区| 亚洲一区二区综合| 欧美日本国产一区| 在线播放中文字幕一区| 香蕉久久久久久久av网站| 亚洲国产人成综合网站| 午夜在线不卡| 国产精品久久77777| 亚洲伦伦在线| 久久夜色精品国产噜噜av| 一本久道久久久| 欧美成人69av| 在线视频观看日韩| 久久本道综合色狠狠五月| 亚洲人成网站色ww在线| 久久偷看各类wc女厕嘘嘘偷窃| 欧美体内she精视频| 亚洲欧洲精品一区二区三区不卡 | 亚洲人成网站影音先锋播放| 欧美影院视频| 国产日产欧美一区| 亚洲欧美一区二区激情| 亚洲精品视频在线看| 欧美成人性生活| 在线看片日韩| 免费不卡中文字幕视频| 久久久久国产精品一区三寸| 国产一区二区三区免费观看| 欧美一区二区三区在线视频 | 一本大道久久a久久综合婷婷 | 亚洲视频欧美视频| 久久久人人人| 国内精品伊人久久久久av一坑| 欧美一区午夜精品| 亚洲在线视频观看| 国产精品视频自拍| 欧美一区二区三区在线播放| 亚洲一区精品电影| 国产日韩在线亚洲字幕中文| 久久精品日产第一区二区| 香蕉成人啪国产精品视频综合网| 国产伦精品一区二区三区免费迷| 午夜精品一区二区三区四区| 午夜免费日韩视频| 在线观看欧美视频| 亚洲黄色精品| 国产精品r级在线| 欧美在线观看日本一区| 欧美中文字幕视频在线观看| 影音先锋一区| 亚洲日本成人女熟在线观看| 国产精品白丝av嫩草影院| 久久成人免费网| 久久伊人亚洲| 日韩一级精品视频在线观看| 在线视频精品| 激情小说另类小说亚洲欧美| 亚洲国产福利在线| 国产精品裸体一区二区三区| 久久视频在线免费观看| 欧美激情视频免费观看| 国产欧美精品在线| 免费欧美电影| 国产精品第13页| 榴莲视频成人在线观看| 欧美片网站免费| 久久久夜色精品亚洲| 欧美久久久久免费| 久久婷婷亚洲| 国产精品久久久久久影视| 女同性一区二区三区人了人一| 欧美精品久久99久久在免费线| 亚洲欧美日韩天堂| 女人色偷偷aa久久天堂| 久久av一区二区三区漫画| 欧美激情久久久| 久久久久看片| 国产精品毛片一区二区三区| 欧美黄色片免费观看| 国产日韩欧美一区二区三区在线观看| 欧美成人午夜77777| 国产免费观看久久黄| 亚洲精品日产精品乱码不卡| 红桃视频一区| 亚洲免费人成在线视频观看| 99re热这里只有精品免费视频| 欧美在线观看网址综合| 午夜一区不卡| 欧美日韩精品久久久| 亚洲国产成人tv| 影音先锋亚洲电影| 久久成人精品电影| 欧美在线网站| 亚洲国产精品视频一区| 国产一区在线看| 最新高清无码专区| 狠狠综合久久av一区二区老牛| 亚洲欧洲一区二区三区在线观看| 国产欧美一级| 亚洲专区在线视频| 亚洲一区二区影院| 欧美日韩在线播放一区二区| 欧美www视频| 国精品一区二区| 性高湖久久久久久久久| 欧美在线观看一区二区三区| 欧美视频三区在线播放| 亚洲精品日韩欧美| 99视频超级精品| 欧美另类变人与禽xxxxx| 亚洲国产欧美在线 | 亚洲视频久久| 欧美日韩另类国产亚洲欧美一级| 欧美大片一区| 日韩一级裸体免费视频| 欧美日韩小视频| 一区二区欧美激情| 午夜在线精品偷拍| 国内外成人在线视频| 久久久之久亚州精品露出| 欧美成人a∨高清免费观看| 91久久精品国产91久久性色| 欧美国产精品久久| 夜夜嗨av一区二区三区中文字幕| 这里只有精品电影| 国产精品久久久久久久久借妻| 亚洲一二三区精品| 久久久久久夜精品精品免费| 在线观看91精品国产麻豆| 欧美成人精品高清在线播放| 99re66热这里只有精品4| 欧美一区永久视频免费观看| 一区二区三区在线视频播放| 欧美精品日韩| 性欧美暴力猛交69hd| 欧美国产三级| 亚洲一区二区三区视频播放| 国产乱码精品一区二区三| 久久综合九色综合欧美就去吻| 亚洲激情中文1区| 欧美在线亚洲在线| 亚洲精品日韩在线观看| 国产精品地址| 免费成人美女女| 亚洲一区二区三区在线看| 欧美成人精品影院| 午夜伦欧美伦电影理论片| 亚洲国产精品视频一区| 国产精品毛片a∨一区二区三区|国| 久久国产精品久久久久久电车| 亚洲国产一区视频| 久久精品亚洲热| 这里只有视频精品| 在线观看国产日韩| 国产欧美日韩亚洲一区二区三区| 久久五月天婷婷| 午夜精品免费| 亚洲乱码国产乱码精品精98午夜 | 美女精品自拍一二三四| 亚洲天堂成人| 亚洲国产欧美久久| 亚洲黄色成人| 激情视频一区| 亚洲综合色噜噜狠狠| 亚洲黄色一区| 国产亚洲女人久久久久毛片| 欧美午夜免费影院| 免费成人毛片| 另类激情亚洲| 久久久久欧美精品| 欧美一区二区三区播放老司机|