從網上看了幾篇關於記憶體對齊的文章,以下是我的理解:
首先需要知道 可以通過以下命令設定對齊係數:
#pragma pack(n) //n可以取1,2,4,8,16等,預設一般是8或16
先看一下記憶體對齊的規則:
1、 對於結構的各個成員,第乙個成員位於偏移為0的位置,以後每個資料成員的偏移位置分兩種情況:
#pragma pack(n) 中的
n(對齊係數)
與 要定位的
資料成員的
自身長度比較
(1) n較小: 該成員偏移的
起始位置(相對於第乙個成員的偏移位置)
需要為n的整數倍
(2) 該成員的自身長度較小: 該成員偏移的
起始位置(相對於第乙個成員的偏移位置)
需要為自身長度的整數倍
2、 在資料成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個數值進行。最後結構體的大小應該為較小數值的整數倍.
了解了對齊規則,下面舉幾個例子:
struct
st1 ;
struct
st2{
short
c ;char
a ;
intb ; ;
此處假設 char佔1位元組, int佔4位元組 ,short佔兩個位元組
#pragma pack(4)時:
sizeof(st1) = 12 sizeof(st2) = 8
首先分析結構體st1
根據上述規則
1成員a佔乙個位元組起始位置為0,
成員b佔4位元組, 與
對齊係數n比較,大小相同
. 所以
成員b的起始位置應為4的整數倍
由於a只佔乙個位元組,所以 需要補三個空位元組
, b的起始位置為4
成員c佔2個位元組
, 與對其
係數n(4)
比較, c長度較小, 成員c的
起始位置為2(c所佔位元組)的整數倍
c的起始位置為 8(a佔1個位元組,後面補了3個,b佔4個, 所以前面所佔位置為0-7 , 下一位置是8剛好是2的整數倍)
經規則1分析後 結構體內存儲存為: a000 bbbb cc 0代表補齊的記憶體
根據上述規則2,
整個結構體也需要對齊, st1中最大成員大小為4(int) 與n(4) 大小相同,所以結構體大小應為4的整數倍, 目前大 小為10, 還需要在後面補齊兩位.
st1在記憶體中最終的儲存為: a000 bbbb cc00
0位儲存a , 1-3位補齊 , 4-7位儲存b , 8-9位儲存c , 10和11位補齊
下面分析結構體st2
規則1:
c佔2位元組 起始位置為0,0-1位儲存c
a佔1位元組 12位儲存a
b佔4位元組 4=n b的起始位置為4的整數倍, b的起始位置為4,第3位補齊
4-7位儲存b
規則2:
st2中成員最大為4, n也為4 , 所以結構體大小應為4的整數倍, 由於此時結構體大小剛好為8,所以不需要補位,
綜上st2的儲存為 cca0 bbbb
再談論一下#pragma pack(2)時:
sizeof(st1) = 8 sizeof(st2) = 8
結構體st1:
規則1:
a佔1位元組 起始位置為0,
0位儲存a
b佔4位元組 4>2(前面定義的對齊係數) , 所以b的起始位置應為2(4與2較小的)的整數倍, 1位補位,
2-5位儲存b
c佔2位元組 2=2 , c的起始位置為2的整數倍,
6-7位儲存c
規則2:
st1中成員最大為4 , n=2 , 4>2 ,所以結構體大小為2的整數倍
n=2時結構體st1的儲存為 a0bbbbcc
結構體st2:
規則1:
c佔2位元組 起始位置為 0,0-1位儲存c
a佔1位元組 1<2 a的起始位置為2,2位儲存a
b佔 4位元組 4>2 b的起始位置為2的整數倍,b的起始位置為4,3位補位,4-7位儲存b
規則2:
結構體st2的最大成員大小為4, 4>2 結構體大小為2的整數倍
綜上結構體st2的儲存為 cca0bbbb
其他情況都是根據那兩條規則分析就可以了
記憶體對齊問題
一直困惑自己有兩個問題 1.程式為什麼要做記憶體對齊?1.處理器訪問記憶體是粒度為多位元組時,如果資料不是在邊界處,則,處理器需要分多個時鐘週期進行資料的訪問。2.增加可移植性。並非所有的處理器都可以訪問任何位址,可能出現硬體錯誤。具體可以參考 2.struct中如何計算記憶體對齊?先說說c語言中s...
記憶體對齊問題
首先由乙個程式引入話題 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劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作...