亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

深入剖析C++中的struct結構體字節對齊

2020-05-23 14:04:08
字體:
來源:轉載
供稿:網友
要求數據內存的起始地址的值是某個數k的倍數,這就是所謂的內存對齊,本文就來深入剖析C++中的struct結構體字節對齊,需要的朋友可以參考下
 

什么是字節對齊,為什么要對齊?

現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經常在特 定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。

對齊的作用和原因:各個硬件平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問一個沒有進行對齊的變量的時候會發生錯誤,那么在這種架構下編程必須保證字節對齊.其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對數據存放進行對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那么一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,并對兩次讀出的結果的高低字節進行拼湊才能得到該32bit數據。顯然在讀取效率上下降很多。

結構的存儲分配
編譯器按照結構體成員列表的順序為每個成員分配內存,當存儲成員時需要滿足正確地邊界對齊要求時,成員之間可能出現用于填充地額外內存空間。32位系統每次分配字節數最多為4個字節,64位系統分配字節數最多為8個字節。
以下圖表是在不同系統中基本類型數據內存大小和默認對齊模數:
注:此外指針所占內存的長度由系統決定,在32位系統下為32位(即4個字節),64位系統下則為64位(即8個字節).

C++,struct,字節對齊

沒有#pragma pack宏的對齊
對齊規則:

結構體的起始存儲位置必須是能夠被該結構體中最大的數據類型所整除。
每個數據成員存儲的起始位置是自身大小的整數倍(比如int在32位機為4字節,則int型成員要從4的整數倍地址開始存儲)。
結構體總大?。ㄒ簿褪莝izeof的結果),必須是該結構體成員中最大的對齊模數的整數倍。若不滿足,會根據需要自動填充空缺的字節。
結構體包含另一個結構體成員,則被包含的結構體成員要從其原始結構體內部最大對齊模數的整數倍地址開始存儲。(比如struct a里存有struct b,b里有char,int,double等元素,那b應該從8的整數倍開始存儲。)
結構體包含數組成員,比如char a[3],它的對齊方式和分別寫3個char是一樣的,也就是說它還是按一個字節對齊。如果寫:typedef char Array[3],Array這種類型的對齊方式還是按一個字節對齊,而不是按它的長度3對齊。
結構體包含共用體成員,則該共用體成員要從其原始共用體內部最大對齊模數的整數倍地址開始存儲。
現在給出一個結構體,我們針對win-32和Linux-32進行分析,

例1:

struct MyStruct{  char a;  int b;  long double c;};

解答:
win-32位系統下:
由上圖可知該結構體的最大對齊模數為sizeof(long double)=8;假設MyStruct從地址空間0x0000開始存放。char為1個字節,所以a存放于0x0000中;int為4個字節,根據規則,b存儲的起始地址必須為其對齊模數4的整數倍,所以a后面自動填充空缺字節空間0x0001-0x0003,因此b存放于0x0004-0x0007中。long double是8個字節,由于32位系統每次最多分配4個字節,則首先分配0x0008-0x000B,由于不夠存儲空間,則繼續分配0x000C-0x000F,所以c存儲在0x0008-0x000F中,由于此時總存儲空間為4+4+8=16;則16滿足最大對齊模數sizeof(long double)=8的整數倍;因此,sizeof(MyStruct)=16個字節。
Linux-32位系統下:

由上圖可知該結構體的最大對齊模數為4;假設MyStruct從地址空間0x0000開始存放。char為1個字節,所以a存放于0x0000中;int為4個字節,根據規則,b存儲的起始地址必須為其對齊模數4的整數倍,所以a后面自動填充空缺字節空間0x0001-0x0003,因此b存放于0x0004-0x0007中。long double是12個字節,由于32位系統每次最多分配4個字節,則首先分配0x0008-0x000B,由于不夠存儲空間,則繼續分配0x000C-0x000F,仍然不滿足存儲c,則繼續分配0x0010-0x0013,所以c存儲在0x0008-0x0013中,由于此時總存儲空間為4+4+12=20;則20滿足最大對齊模數4的整數倍;因此,sizeof(MyStruct)=20個字節。

注:以下的所有例子都是在win-32下實現
例2:

struct B{   char a;   int b;   char c; };

由上圖可知該結構體的最大對齊模數為sizeof(int)=4;假設B從地址空間0x0000開始存放。char為1個字節,所以a存放于0x0000中;int為4個字節,根據規則,b存儲的起始地址必須為其對齊模數4的整數倍,所以a后面自動填充空缺字節空間0x0001-0x0003,因此b存放于0x0004-0x0007中。c也是char類型,所以c存放在0x0008中;此時結構體B總的大小為4+4+1=9個字節;則9不能滿足最大對齊模數4的整數倍;因此在c的后面自動填充空間0x0009-0x000B,使其滿足最大對齊模數的倍數,最終結構體B的存儲空間為0x0000-0x000B;則sizeof(B)=12個字節。
例3:空結構體

struct C{   };sizeof(C) = 0或sizeof(C);

C為空結構體,在C語言中占0字節,在C++中占1字節。

例4:結構體有靜態成員

struct D{    char a;    int b;    static double c; //靜態成員 };

靜態成員變量存放在全局數據區內,在編譯的時候已經分配好內存空間,所以對結構體的總內存大小不做任何貢獻;因此,sizeof(D)=4+4=8個字節
例5:結構體中包含結構體

struct E{   int a;   double b;   float c; }; struct F{   char e[2];   int f;   short h;   struct E i; };

在結構體E中最大對齊模數是sizeof(double)=8;且sizeof(E)=8+8+8=24個字節;在結構體F中,除了結構體成員E之外,其他的最大對齊模數是sizeof(int)=4;又因為結構體E中最大對齊模數是sizeof(double)=8;所以結構體F的最大對齊模數取E的最大對齊模數8;因此,sizeof(F)=4+4+8+24=40個字節。
例6:結構體包含共用體

union union1 {   long a;   double b;   char name[9];   int c[2]; }; struct E{   int a;   double b;   float c;   union1 MyUnion; };

共用體中的最大對齊模式是sizeof(double)=8;則sizeof(union1)=16;結構體E的最大對齊模數也是8;則sizeof(E)=8+8+8+16=40個字節。
例7:結構體包含指針成員

typedef struct A{   char a;   int b;   float c;   double d;   int *p;   char *pc;   short e; }A;

結構體包含的指針成員的大小根據系統類型決定,由于這里是在win-32位系統下分析,則指針大小為4個字節;因此,結構體A的最大對齊模數為sizeof(double)=8;則sizeof(A)=4+4+8+8+4+4+8=40個字節。

存在#pragma pack宏的對齊

#pragma pack (n)  //編譯器將按照n個字節對齊 #pragma pack ()   //取消自定義字節對齊方式

對齊規則:
結構,聯合,或者類的數據成員,第一個放在偏移為0的地方,以后每個數據成員的對齊,按照#pragma pack指定的數值和自身對齊模數中較小的那個。
例8:按指定的對齊模數

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

在結構體G中成員變量的最大對齊模數是sizeof(double)=8;又因為指定對齊模數是2;所以取其較小者2為結構體G的最大對齊模數;則sizeof(G)=2+4+8+2=16;由于16是2的整數倍,則不需要填充。

總結
在分析結構體字節對齊時,首先確定有沒有利用#pragma pack()宏定義指定對齊模數;根據情況對應上面進行兩種情況分析,針對不同的系統會得到不同的結果。

補充:
在Visual C++下可以用__declspec(align(#))聲明數據按#字節對齊
GUN C下可以使用以下命令:
__attribute__((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大于n,則按照最大成員的長度來對齊
__attribute__((__packed__)),取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊。
C++11新加關鍵字alignas(n)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
红桃视频成人在线观看| 伊是香蕉大人久久| 国产亚洲精品久久久久久牛牛| 久久久久久久久电影| 亚洲综合在线中文字幕| 国产激情999| 午夜精品国产精品大乳美女| 久久国产精品影片| 69**夜色精品国产69乱| 色噜噜狠狠狠综合曰曰曰| 日本久久久久久久久久久| 91沈先生作品| 久久精品亚洲一区| 久久国产精品久久久久| 欧美尤物巨大精品爽| 欧美高清性猛交| 日韩一区二区三区xxxx| 亚洲欧美中文在线视频| 国产成人精品电影| 国产精品久久久av| 精品亚洲一区二区三区| 色99之美女主播在线视频| 国产精品稀缺呦系列在线| 国产精品久久久久久久午夜| 亚洲四色影视在线观看| 一本大道亚洲视频| 日韩电影中文字幕| 日韩电视剧免费观看网站| 亚洲黄色成人网| 色诱女教师一区二区三区| 久久97精品久久久久久久不卡| 精品国产91久久久久久老师| 国产精品永久在线| 国产精品96久久久久久| 欧美性生交xxxxx久久久| 精品亚洲永久免费精品| 色与欲影视天天看综合网| 日韩精品中文字幕在线观看| 国产女人精品视频| 91亚洲精品久久久久久久久久久久| 日韩精品高清视频| 日韩精品日韩在线观看| 粉嫩老牛aⅴ一区二区三区| 精品国产区一区二区三区在线观看| 清纯唯美亚洲激情| 日韩精品中文字幕久久臀| 欧美精品久久一区二区| 欧美风情在线观看| 国产精品久久激情| 成人福利网站在线观看| 日本在线观看天堂男亚洲| 欧美精品在线免费播放| 日韩中文字幕视频在线| 国产一区二区日韩精品欧美精品| 久久影视电视剧凤归四时歌| 亚洲天堂色网站| 精品久久久久久久久久久久久久| 欧美裸身视频免费观看| 久久久亚洲网站| 国产精品私拍pans大尺度在线| 久久视频免费在线播放| 成人xxxx视频| 国产精品视频yy9099| 91在线观看免费高清完整版在线观看| 国外色69视频在线观看| 久久久精品久久| 精品国内自产拍在线观看| 国外成人性视频| 国产一区二区香蕉| 91手机视频在线观看| 国产一区二区三区视频免费| 92裸体在线视频网站| 国外成人在线直播| 亚洲最大成人免费视频| 亚洲一区第一页| 日韩在线免费av| 国产视频精品自拍| 亚洲人成电影在线| 欧美一区深夜视频| 久久中文字幕在线| 久久久亚洲天堂| 亚洲精选在线观看| 国产精品电影久久久久电影网| 亚洲精品网址在线观看| 在线观看国产成人av片| 夜夜嗨av色一区二区不卡| 91免费在线视频| 久久99亚洲精品| 日本精品久久久久久久| 亚洲男人天堂古典| 亚洲欧美成人在线| 日韩高清av在线| 91国产美女在线观看| 久久精品视频va| 福利微拍一区二区| 91精品久久久久久| 欧美成人一二三| 国产欧美日韩丝袜精品一区| 欧美激情伊人电影| 亚洲男人天堂古典| 69久久夜色精品国产7777| 在线观看久久久久久| 欧美日韩免费看| 久久久久久久97| 国产91色在线| 精品视频www| 91九色单男在线观看| 国产精品久久网| 欧美一区二区三区图| 91大神在线播放精品| 国产黑人绿帽在线第一区| 精品国内亚洲在观看18黄| 精品色蜜蜜精品视频在线观看| 亚洲淫片在线视频| 国外色69视频在线观看| 日韩免费观看视频| 亚洲精品91美女久久久久久久| 亚洲自拍偷拍色图| 精品在线小视频| 色婷婷综合成人av| 在线电影av不卡网址| 91精品国产乱码久久久久久蜜臀| 国内精品久久影院| 欧美贵妇videos办公室| 久久影视免费观看| 91久久精品日日躁夜夜躁国产| 国产视频一区在线| 精品视频久久久久久久| 欧美日韩一区二区三区在线免费观看| 9.1国产丝袜在线观看| 欧洲永久精品大片ww免费漫画| 亚洲国产天堂久久综合网| 国产精品久久久久久一区二区| 国产欧美日韩丝袜精品一区| 日韩精品一区二区视频| 亚洲成人激情视频| 日韩高清免费观看| 欧美一区二三区| 亚洲韩国青草视频| 美女国内精品自产拍在线播放| 最新69国产成人精品视频免费| 欧洲成人免费aa| www.亚洲人.com| 97婷婷大伊香蕉精品视频| 992tv在线成人免费观看| 欧美丝袜第一区| 亚洲精品自拍偷拍| 欧美极品在线视频| 欧美极品欧美精品欧美视频| 欧美二区在线播放| 奇米影视亚洲狠狠色| 亚洲黄色成人网| 亚洲一区美女视频在线观看免费| 亚洲一级黄色片| 国产有码在线一区二区视频| 国产精品99久久久久久人| 亚洲一区制服诱惑| 日韩女优在线播放| 美女少妇精品视频| 亚洲丝袜一区在线| 97久久精品人搡人人玩| 久久久在线免费观看| 成人a免费视频| 国产91在线播放|