国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Linux C語言字節(jié)對齊的那些事

開發(fā) 后端
隨手整理一下C語言中字節(jié)對齊的問題與大家一起分享。一起來看一下吧。

[[418052]]

 最近一口君在做一個項(xiàng)目,遇到一個問題,運(yùn)行于ARM上的threadx在與DSP通信采用消息隊列的方式傳遞消息(最終實(shí)現(xiàn)原理是中斷+共享內(nèi)存的方式),在實(shí)際操作過程中發(fā)現(xiàn)threadx總是crash,于是經(jīng)過排查,是因?yàn)閭鬟f消息的結(jié)構(gòu)體沒有考慮字節(jié)對齊的問題。

隨手整理一下C語言中字節(jié)對齊的問題與大家一起分享。

一、概念 

對齊跟數(shù)據(jù)在內(nèi)存中的位置有關(guān)。如果一個變量的內(nèi)存地址正好位于它長度的整數(shù)倍,他就被稱做自然對齊。比如在32位cpu下,假設(shè)一個整型變量的地址為0x00000004,那它就是自然對齊的。

首先了解什么位、字節(jié)、字

名稱 英文名 含義
bit 1個二進(jìn)制位稱為1個bit
字節(jié) Byte 8個二進(jìn)制位稱為1個Byte
word 電腦用來一次性處理事務(wù)的一個固定長度

字長

一個字的位數(shù),現(xiàn)代電腦的字長通常為16,32, 64位。(一般N位系統(tǒng)的字長是N/8字節(jié)。)

不同的CPU一次可以處理的數(shù)據(jù)位數(shù)是不同的,32位CPU可以一次處理32位數(shù)據(jù),64位CPU可以一次處理64位數(shù)據(jù),這里的位,指的就是字長。

而所謂的字長,我們有時會稱為字(word)。在16位的CPU中,一個字剛好為兩個字節(jié),而32位CPU中,一個字是四個字節(jié)。若以字為單位,向上還有雙字(兩個字),四字(四個字)。

二、對齊規(guī)則

對于標(biāo)準(zhǔn)數(shù)據(jù)類型,它的地址只要是它的長度的整數(shù)倍就行了,而非標(biāo)準(zhǔn)數(shù)據(jù)類型按下面的原則對齊:   數(shù)組 :按照基本數(shù)據(jù)類型對齊,第一個對齊了后面的自然也就對齊了。聯(lián)合 :按其包含的長度最大的數(shù)據(jù)類型對齊。結(jié)構(gòu)體:結(jié)構(gòu)體中每個數(shù)據(jù)類型都要對齊。

三、如何限制定字節(jié)對齊位數(shù)?

1. 缺省

在缺省情況下,C編譯器為每一個變量或是數(shù)據(jù)單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變?nèi)笔〉膶鐥l件:

2. #pragma pack(n)

·  使用偽指令#pragma pack (n),C編譯器將按照n個字節(jié)對齊。· 使用偽指令#pragma pack (),取消自定義字節(jié)對齊方式。

#pragma pack(n) 用來設(shè)定變量以n字節(jié)對齊方式。n字節(jié)對齊就是說變量存放的起始地址的偏移量有兩種情況:

  1.  如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對齊方式
  2.  如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對齊方式。

結(jié)構(gòu)的總大小也有一個約束條件,如果n大于等于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須是n的倍數(shù)。

3. __attribute

另外,還有如下的一種方式:· __attribute((aligned (n))),讓所作用的結(jié)構(gòu)成員對齊在n字節(jié)自然邊界上。如果結(jié)構(gòu)中有成員的長度大于n,則按照最大成員的長度來對齊。· attribute ((packed)),取消結(jié)構(gòu)在編譯過程中的優(yōu)化對齊,按照實(shí)際占用字節(jié)數(shù)進(jìn)行對齊。

4. 匯編.align

匯編代碼通常用.align來制定字節(jié)對齊的位數(shù)。

.align:用來指定數(shù)據(jù)的對齊方式,格式如下:

  1. .align [absexpr1, absexpr2] 

以某種對齊方式,在未使用的存儲區(qū)域填充值. 第一個值表示對齊方式,4, 8,16或 32. 第二個表達(dá)式值表示填充的值。

四、為什么要對齊?

操作系統(tǒng)并非一個字節(jié)一個字節(jié)訪問內(nèi)存,而是按2,4,8這樣的字長來訪問。因此,當(dāng)CPU從存儲器讀數(shù)據(jù)到寄存器,IO的數(shù)據(jù)長度通常是字長。如32位系統(tǒng)訪問粒度是4字節(jié)(bytes), 64位系統(tǒng)的是8字節(jié)。當(dāng)被訪問的數(shù)據(jù)長度為n字節(jié)且該數(shù)據(jù)地址為n字節(jié)對齊時,那么操作系統(tǒng)就可以高效地一次定位到數(shù)據(jù), 無需多次讀取,處理對齊運(yùn)算等額外操作。數(shù)據(jù)結(jié)構(gòu)應(yīng)該盡可能地在自然邊界上對齊。如果訪問未對齊的內(nèi)存,CPU需要做兩次內(nèi)存訪問。

字節(jié)對齊可能帶來的隱患:

代碼中關(guān)于對齊的隱患,很多是隱式的。比如在強(qiáng)制類型轉(zhuǎn)換的時候。例如: 

  1. unsigned int i = 0x12345678 
  2. unsigned char *p=NULL 
  3. unsigned short *p1=NULL 
  4. p=&i;  
  5. *p=0x00 
  6. p1=(unsigned short *)(p+1);  
  7. *p1=0x0000

最后兩句代碼,從奇數(shù)邊界去訪問unsignedshort型變量,顯然不符合對齊的規(guī)定。在x86上,類似的操作只會影響效率,但是在MIPS或者sparc上,可能就是一個error,因?yàn)樗鼈円蟊仨氉止?jié)對齊.

五、舉例

例1:os基本數(shù)據(jù)類型占用的字節(jié)數(shù)

首先查看操作系統(tǒng)的位數(shù)

在64位操作系統(tǒng)下查看基本數(shù)據(jù)類型占用的字節(jié)數(shù): 

  1. #include <stdio.h>  
  2. int main()  
  3.  
  4.     printf("sizeof(char) = %ld\n", sizeof(char));  
  5.     printf("sizeof(int) = %ld\n", sizeof(int));  
  6.     printf("sizeof(float) = %ld\n", sizeof(float));  
  7.     printf("sizeof(long) = %ld\n", sizeof(long));                                    
  8.     printf("sizeof(long long) = %ld\n", sizeof(long long));  
  9.     printf("sizeof(double) = %ld\n", sizeof(double));  
  10.     return 0;  

例2:結(jié)構(gòu)體占用的內(nèi)存大小--默認(rèn)規(guī)則

考慮下面的結(jié)構(gòu)體占用的位數(shù) 

  1. struct yikou_s  
  2.  
  3.     double d;  
  4.     char c;  
  5.     int i;  
  6. } yikou_t; 

執(zhí)行結(jié)果

  1. sizeof(yikou_t) = 16 

在內(nèi)容中各變量位置關(guān)系如下

其中成員C的位置還受字節(jié)序的影響,有的可能在位置8

編譯器給我們進(jìn)行了內(nèi)存對齊,各成員變量存放的起始地址相對于結(jié)構(gòu)的起始地址的偏移量必須為該變量類型所占用的字節(jié)數(shù)的倍數(shù), 且結(jié)構(gòu)的大小為該結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)的倍數(shù)。

對于偏移量:變量type n起始地址相對于結(jié)構(gòu)體起始地址的偏移量必須為sizeof(type(n))的倍數(shù)結(jié)構(gòu)體大小:必須為成員最大類型字節(jié)的倍數(shù) 

  1. char: 偏移量必須為sizeof(char) 即1的倍數(shù)  
  2. int: 偏移量必須為sizeof(int) 即4的倍數(shù) 
  3. float: 偏移量必須為sizeof(float) 即4的倍數(shù)  
  4. double: 偏移量必須為sizeof(double) 即8的倍數(shù) 

例3:調(diào)整結(jié)構(gòu)體大小

我們將結(jié)構(gòu)體中變量的位置做以下調(diào)整: 

  1. struct yikou_s  
  2.  
  3.     char c;  
  4.     double d;  
  5.     int i;  
  6. } yikou_t; 

執(zhí)行結(jié)果 

  1. sizeof(yikou_t) = 24 

各變量在內(nèi)存中布局如下:

當(dāng)結(jié)構(gòu)體中有嵌套符合成員時,復(fù)合成員相對于結(jié)構(gòu)體首地址偏移量是復(fù)合成員最寬基本類型大小的整數(shù)倍。

例4:#pragma pack(4) 

  1. #pragma pack(4)  
  2. struct yikou_s  
  3.  
  4.     char c; 
  5.     double d;  
  6.     int i;  
  7. } yikou_t;  
  8. sizeof(yikou_t) = 16 

例5:#pragma pack(8) 

  1. #pragma pack(8)  
  2. struct yikou_s  
  3.  
  4.     char c;  
  5.     double d;  
  6.     int i;  
  7. } yikou_t;  
  1. sizeof(yikou_t) = 24 

例6:匯編代碼

舉例:以下是截取的uboot代碼中異常向量irq、fiq的入口位置代碼:

六、匯總實(shí)力

有手懶的同學(xué),直接貼一個完整的例子給你們: 

  1. #include <stdio.h>  
  2. main()  
  3.  
  4. struct A {  
  5.     int a;  
  6.     char b;  
  7.     short c;  
  8. };  
  9. struct B {  
  10.     char b;  
  11.     int a;  
  12.     short c;  
  13. };  
  14. struct AA {  
  15.    // int a;  
  16.     char b;  
  17.     short c; 
  18.  };  
  19. struct BB {  
  20.     char b; 
  21.     // int a;  
  22.     short c;  
  23. };   
  24. #pragma pack (2) /*指定按2字節(jié)對齊*/  
  25. struct C {  
  26.     char b;  
  27.     int a;  
  28.     short c;  
  29. };  
  30. #pragma pack () /*取消指定對齊,恢復(fù)缺省對齊*/  
  31. #pragma pack (1) /*指定按1字節(jié)對齊*/  
  32. struct D {  
  33.     char b;  
  34.     int a;  
  35.     short c;  
  36. };  
  37. #pragma pack ()/*取消指定對齊,恢復(fù)缺省對齊*/  
  38. int s1=sizeof(struct A);  
  39. int s2=sizeof(struct AA);  
  40. int s3=sizeof(struct B);  
  41. int s4=sizeof(struct BB);  
  42. int s5=sizeof(struct C);  
  43. int s6=sizeof(struct D);  
  44. printf("%d\n",s1);  
  45. printf("%d\n",s2);  
  46. printf("%d\n",s3);  
  47. printf("%d\n",s4);  
  48. printf("%d\n",s5);  
  49. printf("%d\n",s6);  
  50.  

 

責(zé)任編輯:龐桂玉 來源: C語言與C++編程
相關(guān)推薦

2021-08-30 12:05:46

Linux字節(jié)對齊代碼

2021-08-06 11:50:49

Linux 字節(jié)對齊Linux 系統(tǒng)

2017-05-15 21:50:54

Linux引號

2018-04-11 08:54:16

Linux ARM存儲分布

2014-06-06 16:08:17

初志科技

2020-07-29 08:14:59

云計算云遷移IT

2011-09-19 15:40:35

2017-11-20 09:00:34

Linux服務(wù)器時間同步

2011-05-19 16:47:50

軟件測試

2012-05-01 08:06:49

手機(jī)

2012-05-31 09:53:38

IT風(fēng)云15年

2013-12-12 17:50:36

開源系統(tǒng)Linux

2015-08-20 09:17:36

Java線程池

2017-03-08 08:53:44

Git命令 GitHub

2015-09-14 09:28:47

2012-10-08 11:55:05

2021-08-11 21:46:47

MySQL索引join

2021-03-18 16:05:20

SSD存儲故障

2015-08-13 10:54:46

2009-02-19 10:21:00

路由多WAN口
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

欧美高清xxxxxkkkkk| 国产精品色在线| 亚洲欧美日韩精品久久久| 久久精品国产第一区二区三区 | 久久久久国产精品一区二区| 久久久无码中文字幕久...| 欧美激情一区二区三区不卡| 深夜宅男网站免费进入| 7777精品伊人久久久大香线蕉最新版| 久久电影tv| 45www国产精品网站| 中文一区二区| 超碰97人人射妻| 欧美日韩你懂的| 99re热精品视频| 久久99精品久久久久久久青青日本 | 91久久午夜| 天天夜碰日日摸日日澡性色av| 专区另类欧美日韩| av在线网址观看| 国外成人在线视频| 日本成人中文字幕在线视频| 免费成人黄色网址| 欧美精品一区二区久久久| 全球av集中精品导航福利| 色999五月色| 亚洲综合久久久久| 成人精品高清在线视频| 痴汉一区二区三区| 国产精品视频看| 午夜羞羞小视频在线观看| 欧美一区二区色| 精品一二线国产| 九色网友自拍视频手机在线| 偷窥自拍亚洲色图精选| 91社区在线观看| 日韩免费中文专区| 欧美亚洲动漫精品| 老司机在线精品视频| 午夜伦全在线观看| 在线观看久久久久久| 亚洲成av人片一区二区密柚| 欧美在线观看www| 欧美一区日韩一区| 国产精品亚洲人成在99www| a级网站在线观看| 欧洲视频一区二区| 网友自拍一区| 久久无码高潮喷水| 亚洲第一精品自拍| 欧美成人嫩草网站| 九七影院97影院理论片免费| 亚洲精品在线看| 国产欧美日韩亚洲一区二区三区| 黄色三级电影网| 中文字幕日韩欧美在线 | 五月激情六月综合| 日韩精品视频一区二区三区| 欧美精品一区二区三区四区五区| 五月激情六月综合| 国产日产精品_国产精品毛片| 日韩avxxx| 亚洲性线免费观看视频成熟| 久久五月激情| av小片在线| 91精品免费看| 亚洲色图另类专区| 77成人影视| 青草青青在线视频| 亚洲日本欧美中文幕| 蜜桃久久久久久| 四虎影院观看视频在线观看| 国产在线资源一区| 欧美日韩一区二区在线视频| 欧美精品一区二区三区久久久竹菊| 99不卡视频| 午夜精品国产精品大乳美女| 国产色产综合色产在线视频| 激情综合婷婷| 亚洲人辣妹窥探嘘嘘| 欧美激情亚洲国产| 国产精品国模大尺度视频| 国产精品qvod| 午夜爽爽爽男女免费观看影院| 欧美日韩国产va另类| 久久亚洲综合色一区二区三区| 日本在线一区二区| 国产又黄又猛视频| 久久免费在线观看| 一区二区三区在线看| 日韩欧美午夜| 国产美女性感在线观看懂色av| 国产乱人伦精品一区二区| 欧美手机在线视频| 麻豆91精品| 不卡福利视频| 精品www久久久久奶水| 欧美极品第一页| 亚洲精品午夜久久久| 91麻豆精品国产91久久久平台| 欧美美乳在线| 欧美精彩一区二区三区| 欧美大片免费久久精品三p| 久久精品99国产精品| 欧美大片免费观看网址| 欧美久久久久久久久久久久久| 欧美日韩福利电影| 亚洲午夜久久久久久久久电影网 | 最新欧美电影| 97国产精东麻豆人妻电影| 久久久久久国产精品久久| 国产网站一区二区| 久久综合色占| av男人的天堂在线| 国产高清精品软男同| 美女撒尿一区二区三区| 亚洲国产毛片aaaaa无费看 | 午夜免费高清视频| 欧美诱惑福利视频| 国产精品成人a在线观看| 91免费在线视频观看| 亚洲国产精品av| 免费视频一区二区三区在线观看| 色播亚洲视频在线观看| 亚洲欧美一区二区三区四区 | 一区二区三区国产精华| 午夜不卡视频| 欧美性受xxxx黑人猛交88| 欧美精品在线播放| 香港成人在线视频| 视频一区视频二区中文| 亚洲一区二区av| 亚洲美女主播视频免费观看| 精品国产一区二区三区免费| 在线看日韩av| 亚洲成人精品一区| 免费在线看成人av| a级日韩大片| 亚洲视频tv| aa免费在线观看| av资源站久久亚洲| 久久精品91久久久久久再现| 亚洲伊人伊色伊影伊综合网| 日韩av电影一区| 天海翼精品一区二区三区| 黄色片网站在线| 成人中文字幕av| 精品乱子伦一区二区三区| 久久伊人色综合| 在线观看视频一区| 91蜜桃网址入口| 亚洲美女网站| 老司机aⅴ在线精品导航| 成人超碰在线| 三上悠亚在线观看二区| 中文字幕在线亚洲精品| 国产精品丝袜久久久久久高清 | 国产亚洲欧美日韩一区二区| 亚洲国产日韩一区二区| 国产米奇在线777精品观看| 精品国产aⅴ| 超碰这里只有精品| 欧美精品电影| www亚洲天堂| 美女在线免费视频| 91免费观看| 久久久亚洲欧洲日产国码aⅴ| 欧美丰满少妇xxxxx高潮对白 | 精品一二三区视频| 777精品久无码人妻蜜桃| 国产丝袜不卡| 亚洲午夜av在线| 中文字幕人成不卡一区| 精品国产免费视频| 日本wwwcom| 精品午夜电影| 日韩一区中文字幕| 91精品久久久久久久久中文字幕| 久久国产乱子伦免费精品| 福利成人导航| 成人性视频免费网站| 欧美一进一出视频| 亚洲精品69| 午夜精品久久久久久| 亚洲激情电影在线| 欧美日韩一区自拍| 波霸ol色综合久久| 亚洲欧美日韩精品在线| 香港久久久电影| 69堂精品视频| 亚洲黄色av网址| 蜜桃av噜噜一区| 91沈先生在线观看| 爱情电影网av一区二区| 中文字幕在线不卡国产视频| 欧美国产视频一区二区| 欧美日韩在线视频免费观看| 亚洲欧美影音先锋| 国产树林野战在线播放| 午夜免费欧美电影|