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

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
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>
            亚洲欧美电影在线观看| 国产精品电影在线观看| 国一区二区在线观看| 久久国产天堂福利天堂| 欧美在线视频一区| 亚洲高清在线观看| 亚洲人成高清| 国产精品激情电影| 久久另类ts人妖一区二区| 免费h精品视频在线播放| 亚洲免费av片| 午夜日本精品| 亚洲国产日韩一区| 一本一道久久综合狠狠老精东影业| 国产精品久久久久久久久久久久| 久久精品亚洲国产奇米99| 久久日韩粉嫩一区二区三区| 一本色道久久精品| 欧美在线不卡| 亚洲桃花岛网站| 欧美在线黄色| 一区二区三区免费观看| 午夜精品久久久久久久久久久久久| 狠狠色狠狠色综合系列| 亚洲免费高清视频| 国产一区观看| aaa亚洲精品一二三区| 在线观看欧美精品| 亚洲性视频网址| 亚洲精品国产精品国自产观看| 亚洲永久字幕| 中日韩美女免费视频网址在线观看| 欧美亚洲视频在线观看| 在线视频你懂得一区 | 在线亚洲精品| 久久久久一区二区| 欧美在线观看视频一区二区三区 | 99视频一区二区| 激情久久久久久久| 亚洲香蕉在线观看| 日韩午夜电影| 免费久久99精品国产自| 久久久久久9| 欧美大片国产精品| 午夜伦欧美伦电影理论片| 久久婷婷av| 久久精品国产亚洲一区二区三区| 欧美日本免费| 亚洲电影第三页| 樱花yy私人影院亚洲| 亚洲一区影院| 午夜精品久久久久| 欧美日韩一区二区精品| 欧美激情区在线播放| 精品88久久久久88久久久| 亚洲欧美制服中文字幕| 性久久久久久| 国产欧美日韩在线视频| 亚洲午夜电影在线观看| 夜夜嗨av色一区二区不卡| 欧美成人黑人xx视频免费观看| 乱人伦精品视频在线观看| 精品成人国产| 久色成人在线| 欧美激情一区二区三区在线视频观看 | 欧美日韩国产一区二区三区地区 | 欧美成人午夜77777| 精品88久久久久88久久久| 久久激情视频| 麻豆精品一区二区综合av | 国产一区二区三区不卡在线观看| 亚洲午夜精品久久久久久app| 中文在线不卡| 国产精品五月天| 欧美一区二区三区在线观看 | 欧美亚洲综合网| 国产三级欧美三级| 欧美一区二区啪啪| 欧美大胆成人| 亚洲一区二区三区四区在线观看| 欧美色123| 欧美一级视频精品观看| 免播放器亚洲一区| 99re亚洲国产精品| 国产精品美女久久福利网站| 欧美在线一二三四区| 欧美电影在线观看| 亚洲一区二区精品在线| 国产三区精品| 免费久久99精品国产自在现线| 亚洲精品在线观看视频| 久久成人一区| 亚洲精品一区二| 国产精品三上| 老司机精品视频网站| 一区二区三区久久| 久久综合中文字幕| 亚洲一区二区3| 一色屋精品视频免费看| 欧美日韩一区二区三区免费| 久久精品国产免费观看| 亚洲裸体俱乐部裸体舞表演av| 久久成人精品电影| 欧美精品播放| 欧美一区二区久久久| 亚洲国产综合在线| 久久精品国产一区二区三区免费看 | 久久蜜桃精品| 亚洲伊人色欲综合网| 亚洲成色最大综合在线| 午夜天堂精品久久久久| 亚洲精品免费看| 韩国av一区二区三区四区| 欧美日韩一级黄| 免费成人黄色| 久久久精品999| 亚洲欧美日韩久久精品| 亚洲精品永久免费| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲精选中文字幕| 欧美成人综合网站| 久久成人精品无人区| 亚洲一区二区免费| 亚洲免费高清| 亚洲人成艺术| 亚洲国产天堂久久综合网| 国外成人在线视频| 国产亚洲综合性久久久影院| 国产精品日韩高清| 国产精品海角社区在线观看| 欧美日韩亚洲高清| 欧美激情影音先锋| 欧美成人按摩| 欧美成人网在线| 欧美成人一区二区| 欧美成年人视频网站| 久久一区二区三区av| 久久久蜜桃一区二区人| 久久久99久久精品女同性| 欧美在线观看一区二区三区| 性欧美大战久久久久久久久| 亚洲欧美日韩区| 欧美亚洲视频一区二区| 欧美在线免费视屏| 久久精品国产欧美激情| 久久视频精品在线| 欧美成人dvd在线视频| 欧美大片在线观看一区二区| 欧美大成色www永久网站婷| 欧美成人综合| 国产精品r级在线| 国产精品午夜视频| 国产资源精品在线观看| 在线观看日韩专区| 亚洲精品小视频在线观看| 99视频有精品| 亚洲欧美视频一区二区三区| 欧美在线视频免费观看| 欧美96在线丨欧| 亚洲欧洲精品一区| 中文亚洲视频在线| 久久av老司机精品网站导航| 久久久蜜桃精品| 欧美日本高清视频| 国产欧美丝祙| 亚洲第一福利在线观看| 日韩午夜电影av| 久久丁香综合五月国产三级网站| 久久亚洲精品欧美| 亚洲日本免费| 欧美一区二区免费观在线| 欧美不卡视频一区发布| 国产精品久久国产愉拍| 在线精品视频在线观看高清| 一区二区高清视频在线观看| 欧美在线视频导航| 欧美日韩在线一区二区| 国产日韩av一区二区| 在线观看欧美日韩| 亚洲专区一区| 欧美国产大片| 亚洲综合首页| 欧美精品福利在线| 激情综合中文娱乐网| 亚洲免费在线观看视频| 猫咪成人在线观看| 亚洲一品av免费观看| 免费亚洲电影在线| 国产日韩一区二区三区在线播放 | 亚洲女爱视频在线| 欧美 亚欧 日韩视频在线| 亚洲午夜未删减在线观看| 久久夜色精品一区| 国产深夜精品福利| 亚洲视频一区在线| 亚洲黄色av| 免费观看成人| 精品成人一区二区三区| 欧美一区二区三区视频| 一区二区免费看|