内存对齐和内存补齐
1. 何為內存對齊,內存補齊
-內存對齊: 第一個數據成員放在offset為0的地方,對齊按照對齊系數和自身所占用的字節數中,兩者比較小的那個進行對齊。
-內存補齊 在struct或者union數據成員完成各自對齊之后,struct或者union本身也要對齊,對齊按照對齊系數和struct或者union中最大數據成員長度中比較小的那個進行。先局部成員對齊,然后再全局對齊。
2.內存對齊優點
性能原因:數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。內存是一組一組讀取的(4個一組或8個一組讀取),為了訪問未對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問(數據存放在同一個組只需要一次讀取,如果分散在不同的組,需要兩次讀取)。
3.例題解答
struct One{double d;char c;int i; } struct Two{char c;double d;int i; }問在#pragma pack(4)和#pragma pack(8)的情況下,結構體的大小分別是多少?
(1)針對#pragma pack(4)
Struct One:
內存對齊: double 占8個字節(對齊系數是4,double占據8個字節,兩者取小的,所以對齊系數是4),偏移量從0開始,d占據8個字節。c占據1個字節(對齊系數是4,1和4兩者取最小值),c實際占據第8個字節。i占據4個字節(對齊系數就是4),下一個地址為12為4的倍數,因此,i占據從12-15的字節。中間第9,10,11將被空出。
內存補齊:內存對齊系數為4,最大內存長度是8,因此下一個內存地址位將按照4的倍數進行補齊,由于下一個地址位是16,因此無需進行補齊。所以在#pragma pack(4)情況下,struct One所需內存為16字節。
Struct Two:
內存對齊: c占用內存1個字節(內存系數是4,對齊方式1和4取小),占用第0號內存。d占用內存是8個字節(內存系統是4,8和4取小的,所以內存系數是4),d占據內存位置為4-11,i占4個字節(內存對齊方式按照4的倍數),占用12-15位內存。中間的第1,2,3地址位將被空出。
內存補齊:內存對齊系數為4,最大內存長度是8,因此下一個內存地址位將按照4的倍數進行補齊,由于下一個地址位是16,因此無需進行補齊。所以在#pragma pack(4)情況下,struct Two所需內存為16字節。
(1)針對#pragma pack(8)
Struct One:
內存對齊: double 占8個字節(對齊系數是8,double占據8個字節,內存對齊方式是8的倍數),偏移量從0開始,d占據8個字節。c占據1個字節(對齊系數是8,1和8兩者取小的值),c實際占據第8個字節。i占據4個字節(對齊系數就是8,8和4取小的值),下一個地址為12為4的倍數,因此,i占據從12-15的字節。中間第9,10,11將被空出。
內存補齊:內存對齊系數為8,最大內存長度是8,因此下一個內存地址位將按照4的倍數進行補齊,由于下一個地址位是16,因此無需進行補齊。所以在#pragma pack(8)情況下,struct One所需內存為16字節。
Struct Two:
內存對齊: c占用內存1個字節(內存系數是8,對齊方式1和8取小),占用第0號內存。d占用內存是8個字節(內存系統是8,所以內存系數是8),d占據內存位置為8-15,i占4個字節(內存系數是8,所以對齊方式按照4的倍數),占用16-19位內存。中間的第1,2,3,4,5,6,7地址位將被空出。
內存補齊:內存對齊系數為8,最大內存長度是8,因此下一個內存地址位將按照8的倍數進行補齊,由于下一個地址位是20,并非8的倍數,因此需要進行補齊到第23位(內存地址位從第0號開始)。所以在#pragma pack(8)情況下,struct Two所需內存為24字節。
注:32位機器默認對齊系數是4位,64位機器默認對齊系數是8位。
Union在內存中占用以最長的一致
總結
- 上一篇: Ubuntu16.04通过GPT挂载硬盘
- 下一篇: wxParse无法解析strong标签