一直困惑自己有兩個問題:
1.程式為什麼要做記憶體對齊?
1.處理器訪問記憶體是粒度為多位元組時,如果資料不是在邊界處,則,處理器需要分多個時鐘週期進行資料的訪問。
2.增加可移植性。並非所有的處理器都可以訪問任何位址,可能出現硬體錯誤。
具體可以參考:
2.struct中如何計算記憶體對齊?
先說說c語言中struct結構計算記憶體對齊,實際上struct計算記憶體對齊的時候採用了兩步:
1.struct資料成員對齊:
對於結構的各個成員,第乙個成員位於偏移為
0的位置,以後每個資料成員的偏移量必須是
min(#pragma pack()
指定的數,這個資料成員的自身長度
)的倍數;
#pragma pack(),如果沒有明確定義,則採用預設值,其中vc6.0中採用的預設值為8;
2.struct結構自身對齊:
在資料成員完成各自對齊之後,結構
(或聯合
)本身也要進行對齊,對齊將按照min(
#pragma pack
指定的數值,結構
(或聯合
)最大資料成員長度);
說白了,這些對齊都是為了處理器記憶體訪問服務的。
struct st_data
sizeof(st_data)=2+2+4=8
#pragma pack(8)
struct teststruct4;
struct teststruct5
;#pragma pack()
問題:a),sizeof(teststruct5) = ?
b), teststruct5 的c 後面空了幾個位元組接著是d
teststruct4 中,成員a 是1 位元組預設按1 位元組對齊,指定對齊引數為8,這兩個值中取1,
a按1 位元組對齊;成員b 是4 個位元組,預設是按4 位元組對齊,這時就按4 位元組對齊,
所以 sizeof(teststruct4)應該為8;
teststruct5 中,c 和teststruct4 中的a 一樣,按1 位元組對齊,而d 是個結構,它是8 個位元組,它
按什麼對齊呢?對於結構來說,它的預設對齊方式就是它的所有成員使用的對齊引數中最大的乙個,
teststruct4 的就是4.所以,成員d 就是按4 位元組對齊.成員e 是8 個位元組,它是預設按8
位元組對齊,和指定的一樣,所以它對到8 位元組的邊界上,這時,已經使用了12 個位元組了,所以又添
加了4 個位元組的空,從第16 個位元組開始放置成員e.這時,長度為24,已經可以被8(成員e 按8
位元組對齊)整除.這樣,一共使用了24 個位元組.記憶體布局如下(*表示空閒記憶體,1 表示使用記憶體。
單位為1byete):
a bteststruct4 的記憶體布局:1***,1111,
c teststruct4.a teststruct4.b d
teststruct5 的記憶體布局: 1***, 1***, 1111, ****,11111111
這裡有三點很重要:
首先,每個成員分別按自己的方式對齊,並能最小化長度。
其次,複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在成員是複雜型別時,可以最小化長度。
然後,對齊後的長度必須是成員中最大的對齊引數的整數倍,這樣在處理陣列時可以保證每一項都邊界對齊。
記憶體對齊問題
首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include iostream 45 using namespace std 67 struct st1 8 1314 struct st215 20 21int main 2227 程式的輸出結果為 sizeof st...
記憶體對齊問題
一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作...
記憶體對齊問題
從網上看了幾篇關於記憶體對齊的文章,以下是我的理解 首先需要知道 可以通過以下命令設定對齊係數 pragma pack n n可以取1,2,4,8,16等,預設一般是8或16 先看一下記憶體對齊的規則 1 對於結構的各個成員,第乙個成員位於偏移為0的位置,以後每個資料成員的偏移位置分兩種情況 pra...