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

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

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

2020-01-26 14:35:40
字體:
來源:轉載
供稿:網友

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

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

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

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

2016518170752299.png (675×267)

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

結構體的起始存儲位置必須是能夠被該結構體中最大的數據類型所整除。
每個數據成員存儲的起始位置是自身大小的整數倍(比如int在32位機為4字節,則int型成員要從4的整數倍地址開始存儲)。
結構體總大小(也就是sizeof的結果),必須是該結構體成員中最大的對齊模數的整數倍。若不滿足,會根據需要自動填充空缺的字節。
結構體包含另一個結構體成員,則被包含的結構體成員要從其原始結構體內部最大對齊模數的整數倍地址開始存儲。(比如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
日韩免费高清在线观看| 精品视频在线观看日韩| 国产91色在线播放| 国产精品吹潮在线观看| 欧美精品videofree1080p| 国产精品久久久久久中文字| 国产在线观看一区二区三区| 欧美一级片免费在线| xxxxx91麻豆| 国产日韩换脸av一区在线观看| 国产精品96久久久久久| 亚洲午夜精品久久久久久性色| 日韩欧美一区二区在线| xvideos亚洲| 国产a∨精品一区二区三区不卡| 主播福利视频一区| 不卡av电影院| 成人久久精品视频| 欧美极品少妇xxxxⅹ喷水| 91干在线观看| 国精产品一区一区三区有限在线| 2019中文字幕在线观看| 久久全球大尺度高清视频| 久久人人爽亚洲精品天堂| 欧美日韩国产丝袜美女| 亚洲久久久久久久久久| 久久国产精品久久久久| 久久夜色精品国产| 2021久久精品国产99国产精品| 国产欧美日韩免费看aⅴ视频| 欧美电影在线观看高清| 亚洲男人av电影| 精品亚洲一区二区三区四区五区| 日韩电影在线观看中文字幕| 欧美国产日韩一区二区三区| 精品欧美国产一区二区三区| 欧美成人免费小视频| 97超视频免费观看| 中文字幕在线观看日韩| 成人免费福利视频| 国产精品主播视频| 欧美性猛交xxxx乱大交蜜桃| 国产精品一二三视频| 色婷婷综合久久久久中文字幕1| 午夜精品久久久久久久男人的天堂| 欧美老女人性生活| 久久香蕉国产线看观看网| 91精品国产综合久久香蕉最新版| 搡老女人一区二区三区视频tv| 国产午夜精品全部视频播放| 亚洲人线精品午夜| xxx成人少妇69| 精品视频在线播放色网色视频| 俺去了亚洲欧美日韩| 亚洲综合社区网| 亚洲第一二三四五区| 亚洲一区二区免费| 亚洲免费人成在线视频观看| 久久视频在线观看免费| 欧美日韩国产精品专区| 日韩精品中文字幕在线播放| 日韩一区二区久久久| 亚洲激情在线观看视频免费| 国产精品稀缺呦系列在线| 日韩av123| 日韩高清av一区二区三区| 国产精品电影久久久久电影网| 亚洲国产精品高清久久久| 影音先锋欧美在线资源| 亚洲色图激情小说| 亚洲精品美女久久久| 深夜福利一区二区| 久久久久久久亚洲精品| 在线免费观看羞羞视频一区二区| 国产精品热视频| 国产精品专区一| 日韩一区二区三区国产| 中文字幕亚洲一区在线观看| 国产精品永久免费在线| 91精品国产成人| 欧美剧在线观看| 欧美激情欧美狂野欧美精品| 亚洲精选中文字幕| 日本久久久久久久久久久| 欧美午夜美女看片| 欧美黑人一区二区三区| 欧美成人免费全部观看天天性色| 色偷偷偷综合中文字幕;dd| 久久久综合免费视频| 欧美成年人视频网站| 久久国产精彩视频| 欧美成人合集magnet| 欧美性视频在线| 亚洲国产精品成人va在线观看| 亚洲国产精品成人va在线观看| 成人午夜激情免费视频| 欧美成人精品不卡视频在线观看| 国产精品高潮呻吟久久av黑人| 亚洲日本中文字幕免费在线不卡| 日韩视频免费在线| 久久免费视频在线观看| 中文字幕亚洲综合久久| 欧美日本啪啪无遮挡网站| 91国产高清在线| 午夜精品久久久久久久99热浪潮| 亚洲欧美中文日韩v在线观看| 久久这里只有精品99| 欧美日韩裸体免费视频| 91精品在线影院| 国产在线视频不卡| 亚洲视频第一页| 欧美国产亚洲视频| 最近2019年日本中文免费字幕| 欧美国产亚洲精品久久久8v| 欧美日韩亚洲视频一区| 福利一区福利二区微拍刺激| 国产欧美一区二区三区久久| 91精品国产色综合久久不卡98口| 国产午夜精品一区二区三区| 久久久久久久久久久亚洲| 青草青草久热精品视频在线网站| 国产精品夜色7777狼人| 不卡av电影在线观看| 91免费看国产| 国产+成+人+亚洲欧洲| 国产专区欧美专区| 久久天天躁夜夜躁狠狠躁2022| 日韩电视剧免费观看网站| 亚洲精品久久久久久久久久久| 精品五月天久久| 亚洲综合中文字幕68页| 91亚洲国产成人精品性色| 精品久久久久久久久久久久| 欧美一区二粉嫩精品国产一线天| 亚洲国产精彩中文乱码av在线播放| 欧美精品手机在线| 国内精品免费午夜毛片| 国内精品在线一区| 尤物99国产成人精品视频| 欧美成人精品一区二区| 午夜欧美不卡精品aaaaa| 777午夜精品福利在线观看| 国模私拍视频一区| 日韩小视频在线观看| 欧美激情国产日韩精品一区18| 久久久久久高潮国产精品视| 日韩精品免费在线观看| 日本成人免费在线| 欧美另类暴力丝袜| 久久亚洲精品中文字幕冲田杏梨| 欧美人与物videos| 热久久美女精品天天吊色| 日韩一区视频在线| 色七七影院综合| 亚洲国产小视频在线观看| 成人h视频在线观看播放| 中文字幕不卡在线视频极品| 91免费的视频在线播放| 国产综合视频在线观看| 2018中文字幕一区二区三区| 久久视频免费在线播放| 日韩av网站导航| 亚洲精品福利资源站| 国产日韩av在线|