本文為本人另一個賬號上的文章,那個賬號不要了,乾坤大挪移過來
。
最近遇到結構體內存對齊的問題,發現自己一知半解,于是在網上搜集了些資料,總結如下。
一、規則
每個特定平臺上的編譯器都有自己的默認“對齊系數”(也叫對齊模數)。程序員可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數,其中的n就是你要指定的“對齊系數”,VC++默認 n = 8。對齊分兩步,第一步:數據成員對齊;第二步:結構體對齊。
- 數據成員對齊: 每個結構體成員所分配的存儲位置與起始點的偏移量必須能夠整除min(對齊系數,成員字節數)。
- 結構(或聯合)的整體對齊: 整個結構體所占存儲空間要能整除min(max(成員字節數),對齊系數)。
綜合上面兩點規則推斷:當所有數據成員長度 都 小于 #pragma pack的n值時,這個n值的大小將不產生任何效果。
二、實例說明
為節省時間,只舉例說明“對齊系數”為 2 和 8 時的情形。
(一)對齊系數為2
1、成員數據對齊。
#pragma pack(2) struct test_t { int a; /* 長度4 > 2 按2對齊;起始offset=0 0%2=0;存放位置區間[0,3] */ char b; /* 長度1 < 2 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */ short c; /* 長度2 = 2 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] ,前面空了一個字節*/ char d; /* 長度1 < 2 按1對齊;起始offset=8 8%1=0;存放位置區間[8] */ }; #pragma pack()
成員總大小= 9
2、整體對齊
整體對齊系數 = min((max(int,short,char), 2) = 2
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 10 /* 10%2=0 */
為了更好地說明問題,下面調換一下c和d的位置,再看一下對齊情況。
1、成員數據對齊。
#pragma pack(2) struct test_t { int a; /* 長度4 > 2 按2對齊;起始offset=0 0%2=0;存放位置區間[0,3] */ char b; /* 長度1 < 2 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */ char d; /* 長度1 < 2 按1對齊;起始offset=8 8%1=0;存放位置區間[5] */ short c; /* 長度2 = 2 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] */ }; #pragma pack()
成員
總大小 = 8
2、整體對齊
整體對齊系數 = min((max(int,short,char), 2) = 2
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 8 /* 8%2=0 */
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 8 /* 8%2=0 */
(二) 對齊系數為8
1、成員數據對齊。
#pragma pack(8) struct test_t { int a; /* 長度4 < 8 按4對齊;起始offset=0 0%4=0;存放位置區間[0,3] */ char b; /* 長度1 < 8 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */ short c; /* 長度2 < 8 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] ,前面空一個字節*/ char d; /* 長度1 < 8 按1對齊;起始offset=8 8%1=0;存放位置區間[8] */ }; #pragma pack()
成員總大小 = 9
2、整體對齊
整體對齊系數 = min((max(int,short,char),8) = 4
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 12/* 12%4=0 */
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 12/* 12%4=0 */
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
