大部分的參考資料都是如是說的:
ios
一、平臺緣由(移植緣由):不是全部的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能在某些地址處取某些特定類型的數據,不然拋出硬件異常。
二、性能緣由:數據結構(尤爲是棧)應該儘量地在天然邊界上對齊。緣由在於,爲了訪問未對齊的內存,處理器須要做兩次內存訪問;而對齊的內存訪問僅須要一次訪問。數據結構
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; char b; char c; }; cout << sizeof(AA) << endl; system("pause"); }
這個比較簡單,能夠根據上面的表格能夠直接計算出來。性能
來個有點難度的spa
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; int b; char c; }; cout << sizeof(AA) << endl; system("pause"); }
猜猜結果會是多少? 會是 5 嗎??3d
來詳細瞭解一下:code
實際上會如圖所示嗎???blog
當以如圖的方式存放數據時,系統訪問char a 時,只需讀取一個字節,但當訪問 int b 的時候,先要讀取一個字節,在讀取四個字節,才能讀到int b的值。這樣系統在訪問數據時要先判斷各個數據的字節大小,在進行讀取,這樣就會浪費時間。爲了節省時間,會以下的方式去存儲數據:內存
在存儲數據時,會對char a 補充 3 個字節,這樣在訪問 char a、int b 時,每次只需讀取 4 個字節就能夠,以一種空間換時間方式來提升效率。編譯器
當如圖存放數據以後,整個結構體的大小爲 9 個字節。這與計算輸出的結果不符(還記得,經過程序計算的大小爲 12 個字節),這是爲何嗎??io
還記得前面說的內存對齊的第四條規則嗎??
4.結構體總大小必須是對齊模數的整數倍。
在上面給出了一個表格,上面有常見數據類型的模數,那咱們如何肯定一個結構提的模數呢???
其實結構體的模數等於其內部模數最大的成員類型的模數
struct AA { char a; int b; char c; };
對於結構體AA來講,他的模數就是 4。
則該結構體的大小必須是 4 的整數倍,因此在最後還會補充 3 個字節(以下圖)。
這樣結構體AA的大小就是 12 個字節。
#include <stdlib.h> #include <iostream> using namespace std; int main() { struct AA { char a; int b; char c; }; struct BB { char d; int e; double f; AA g; }; cout << sizeof(BB) << endl; system("pause"); }
先來看看答案:
來分析一下:
到結構AA,來看看結構體AA的狀況:
因此接下來應該以下圖:
由圖可知 結構體BB一共佔據32個字節的內存,到這裏就完了嗎??
還記得 內存對齊的第四條規則嗎??
4.結構體總大小必須是對齊模數的整數倍。
結構體BB的模數爲多少呢??
由於double e 的模數最大爲 8 ,因此BB的模數也爲8。32 是 8 的倍數,因此結構體BB只佔 32 個字節。
能夠經過#pragma pack() 自定義模數的大小。
#include <stdlib.h> #include <iostream> using namespace std; #pragma pack(1) int main() { struct AA { char a; int b; char c; }; struct BB { char d; int e; double f; AA g; }; cout << sizeof(BB) << endl; system("pause"); }
將模數的大小自定義爲 1 後,運行結果以下:
當模數大小定義爲 2 時,運行結果以下:
能夠本身去試試畫圖理解。