內存變量邊界對齊
阿新 • • 發佈:2017-05-12
轉載 space net names ima logs 分配內存 .net sin
一、什麽是內存對齊
(1) 原理
a) 編譯器按照成員列表的順序給每個成員分配內存.
b) 當成員需要滿足正確的邊界對齊時,成員之間用額外字節填充.
c) 結構體的首地址必須滿足結構體中邊界要求最為嚴格的數據類型所要求的地址.
d) 結構體的大小為其最寬基本類型的整數倍.
(2) 程序設計
1 #include<iostream> 2 3 #include<cstdio> 4 5 #include<string> 6 7 using namespace std; 8 9 struct node1 10 11 {View Code12 13 char c; 14 15 char b; 16 17 int a; 18 19 }n1; 20 21 struct node2 22 23 { 24 25 char c; 26 27 int a; 28 29 char b; 30 31 }n2; 32 33 int main() 34 35 { 36 37 //內存大小 38 39 int size1=sizeof(node1); 40 41 int size2=sizeof(node2); 42 43printf("%d %d\n",size1,size2); 44 45 //具體地址 46 47 //node1 48 49 cout<<(long long)(void*)&n1.c-(long long)(void*)&n1<<endl; 50 51 cout<<(long long)(void*)&n1.b-(long long)(void*)&n1<<endl; 52 53 cout<<(long long)(void*)&n1.a-(longlong)(void*)&n1<<endl; 54 55 //node2 56 57 cout<<(long long)(void*)&n2.c-(long long)(void*)&n2<<endl; 58 59 cout<<(long long)(void*)&n2.a-(long long)(void*)&n2<<endl; 60 61 cout<<(long long)(void*)&n2.b-(long long)(void*)&n2<<endl; 62 63 return 0; 64 65 }
(3) 結果
實驗顯示結果為
(4) 分析
a) node1和node2的成員相同,但成員的順序不一樣,所以總體占用的空間不一樣,驗證了編譯器按照成員列表的順序給每個成員分配內存。
b) 對於node1和node2,分別輸出每個成員的占用空間,發現char c和char b順序緊挨時,各占據一個字節;char a 和char b相隔時,各占據4個字節。驗證了當成員需要滿足正確的邊界對齊時,成員之間用額外字節填充.
c) 實驗表明,內存變量是按邊界對齊。
二、為什麽要按邊界對齊(轉載請註明出處:http://blog.csdn.net/acs713/article/details/25040389)
從處理器的角度來看,需要盡可能減少對內存的訪問次數以實現對數據結構進行更加高效的操作。為什麽呢?因為盡管處理器包含了緩存,但它在處理數據時還得讀取緩存中的數據,讀取緩存的次數當然是越少越好!如上圖所示,在采用邊界對齊的情況下,當處理器需要訪問a_變量和b_變量時都只需進行一次存取(圖中花括號表示一次存取操作)。若不采用邊界對齊,a_變量只要一次處理器操作,而b_變量卻至少要進行兩次操作。對於b_,處理器還得調用更多指令將其合成一個完整的4字節,這樣無疑大大降低了程序效率。
內存變量邊界對齊