欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
也談內存對齊 :: Tony Bai

在最近的項目中,我們涉及到了“內存對齊”技術(shù)。對于大部分程序員來(lái)說(shuō),“內存對齊”對他們來(lái)說(shuō)都應該是“透明的”。“內存對齊”應該是編譯器的“管轄范圍”。編譯器為程序中的每個(gè)“數據單元”安排在適當的位置上。但是C語(yǔ)言的一個(gè)特點(diǎn)就是太靈活,太強大,它允許你干預“內存對齊”。如果你想了解更加底層的秘密,“內存對齊”對你就不應該再透明了。

一、內存對齊的原因
大部分的參考資料都是如是說(shuō)的:
1、平臺原因(移植原因):不是所有的硬件平臺都能訪(fǎng)問(wèn)任意地址上的任意數據的;某些硬件平臺只能在某些地址處取某些特定類(lèi)型的數據,否則拋出硬件異常。
2、性能原因:數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了訪(fǎng)問(wèn)未對齊的內存,處理器需要作兩次內存訪(fǎng)問(wèn);而對齊的內存訪(fǎng)問(wèn)僅需要一次訪(fǎng)問(wèn)。

二、對齊規則
每個(gè)特定平臺上的編譯器都有自己的默認“對齊系數”(也叫對齊模數)。程序員可以通過(guò)預編譯命令#pragma pack(n),n=1,2,4,8,16來(lái)改變這一系數,其中的n就是你要指定的“對齊系數”。

規則:
1、數據成員對齊規則:結構(struct)(或聯(lián)合(union))的數據成員,第一個(gè)數據成員放在offset為0的地方,以后每個(gè)數據成員的對齊按照#pragma pack指定的數值和這個(gè)數據成員自身長(cháng)度中,比較小的那個(gè)進(jìn)行。
2、結構(或聯(lián)合)的整體對齊規則:在數據成員完成各自對齊之后,結構(或聯(lián)合)本身也要進(jìn)行對齊,對齊將按照#pragma pack指定的數值和結構(或聯(lián)合)最大數據成員長(cháng)度中,比較小的那個(gè)進(jìn)行。
3、結合1、2顆推斷:當#pragma pack的n值等于或超過(guò)所有數據成員長(cháng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果。

三、試驗
我們通過(guò)一系列例子的詳細說(shuō)明來(lái)證明這個(gè)規則吧!
我試驗用的編譯器包括GCC 3.4.2和VC6.0的C編譯器,平臺為Windows XP + Sp2。

我們將用典型的struct對齊來(lái)說(shuō)明。首先我們定義一個(gè)struct:
#pragma pack(n) /* n = 1, 2, 4, 8, 16 */
struct test_t {
 int a;
 char b;
 short c;
 char d;
};
#pragma pack(n)
首先我們首先確認在試驗平臺上的各個(gè)類(lèi)型的size,經(jīng)驗證兩個(gè)編譯器的輸出均為:
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4

我們的試驗過(guò)程如下:通過(guò)#pragma pack(n)改變“對齊系數”,然后察看sizeof(struct test_t)的值。

1、1字節對齊(#pragma pack(1))
輸出結果:sizeof(struct test_t) = 8 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數據對齊
#pragma pack(1)
struct test_t {
 int a;  /* 長(cháng)度4 < 1 按1對齊;起始offset=0 0%1=0;存放位置區間[0,3] */
 char b;  /* 長(cháng)度1 = 1 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */
 short c; /* 長(cháng)度2 > 1 按1對齊;起始offset=5 5%1=0;存放位置區間[5,6] */
 char d;  /* 長(cháng)度1 = 1 按1對齊;起始offset=7 7%1=0;存放位置區間[7] */
};
#pragma pack()
成員總大小=8

2) 整體對齊
整體對齊系數 = min((max(int,short,char), 1) = 1
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 8 /* 8%1=0 */ [注1]

2、2字節對齊(#pragma pack(2))
輸出結果:sizeof(struct test_t) = 10 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數據對齊
#pragma pack(2)
struct test_t {
 int a;  /* 長(cháng)度4 > 2 按2對齊;起始offset=0 0%2=0;存放位置區間[0,3] */
 char b;  /* 長(cháng)度1 < 2 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */
 short c; /* 長(cháng)度2 = 2 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] */
 char d;  /* 長(cháng)度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 */

3、4字節對齊(#pragma pack(4))
輸出結果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數據對齊
#pragma pack(4)
struct test_t {
 int a;  /* 長(cháng)度4 = 4 按4對齊;起始offset=0 0%4=0;存放位置區間[0,3] */
 char b;  /* 長(cháng)度1 < 4 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */
 short c; /* 長(cháng)度2 < 4 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] */
 char d;  /* 長(cháng)度1 < 4 按1對齊;起始offset=8 8%1=0;存放位置區間[8] */
};
#pragma pack()
成員總大小=9

2) 整體對齊
整體對齊系數 = min((max(int,short,char), 4) = 4
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 12 /* 12%4=0 */

4、8字節對齊(#pragma pack(8))
輸出結果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數據對齊
#pragma pack(8)
struct test_t {
 int a;  /* 長(cháng)度4 < 8 按4對齊;起始offset=0 0%4=0;存放位置區間[0,3] */
 char b;  /* 長(cháng)度1 < 8 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */
 short c; /* 長(cháng)度2 < 8 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] */
 char d;  /* 長(cháng)度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 */


5、16字節對齊(#pragma pack(16))
輸出結果:sizeof(struct test_t) = 12 [兩個(gè)編譯器輸出一致]
分析過(guò)程:
1) 成員數據對齊
#pragma pack(16)
struct test_t {
 int a;  /* 長(cháng)度4 < 16 按4對齊;起始offset=0 0%4=0;存放位置區間[0,3] */
 char b;  /* 長(cháng)度1 < 16 按1對齊;起始offset=4 4%1=0;存放位置區間[4] */
 short c; /* 長(cháng)度2 < 16 按2對齊;起始offset=6 6%2=0;存放位置區間[6,7] */
 char d;  /* 長(cháng)度1 < 16 按1對齊;起始offset=8 8%1=0;存放位置區間[8] */
};
#pragma pack()
成員總大小=9

2) 整體對齊
整體對齊系數 = min((max(int,short,char), 16) = 4
整體大小(size)=$(成員總大小) 按 $(整體對齊系數) 圓整 = 12 /* 12%4=0 */

四、結論
8字節和16字節對齊試驗證明了“規則”的第3點(diǎn):“當#pragma pack的n值等于或超過(guò)所有數據成員長(cháng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果”。另外內存對齊是個(gè)很復雜的東西,上面所說(shuō)的在有些時(shí)候也可能不正確。呵呵^_^

[注1]
什么是“圓整”?
舉例說(shuō)明:如上面的8字節對齊中的“整體對齊”,整體大小=9 按 4 圓整 = 12
圓整的過(guò)程:從9開(kāi)始每次加一,看是否能被4整除,這里9,10,11均不能被4整除,到12時(shí)可以,則圓整結束。


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
面試???,項目易錯,長(cháng)文詳解C/C 中的字節對齊
C語(yǔ)言學(xué)習筆記
【程序員一枚】C++基礎之內存對齊
字節對齊
C語(yǔ)言結構體對齊問(wèn)題
關(guān)于內存對齊
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久