結構體記憶體對齊總結
阿新 • • 發佈:2018-11-21
首先我們都知道結構體是多個變數的集合,在其中可以存放整型,浮點型等等各種,然後結構體記憶體是如何對齊的呢,他並不是按連續順序去排下去的,首先我們先上一段程式碼
#include<iostream> #include<cstdlib> using namespace std; struct a{ int m; char n; double c; }; struct b{ char o; double p; int j; }; int main() { cout << sizeof(a) << endl; cout << sizeof(b) << endl; system("pause"); }
這段程式碼執行出來的結果得出a的記憶體大小為16,b的記憶體大小為24,同樣的三個型別,只是排列順序不同,結構體的大小就不一樣。下面是對齊規則
結構體記憶體對齊規則
1. 第一個成員在與結構體偏移量為0的地址處。
2. 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處。
對齊數 = 編譯器預設的一個對齊數 與 該成員大小相比中的較小值。
VS中預設的對齊數為8,gcc中的對齊數為4
3. 結構體總大小為:最大對齊數(所有變數型別最大者與預設對齊引數取最小)的整數倍。
4. 如果嵌套了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是
所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
那麼為什麼要記憶體對齊呢
記憶體對齊大大提高了cpu的讀取速率。
1.還有並非所有硬體平臺都可以訪問任何地址上的任何資料,有些硬體平臺也只能訪問某些特定地址處某些特定型別的資料。
2.記憶體對齊的CPU只需要讀取一次,沒有記憶體對齊,CPU則需要讀取兩次。
如何讓結構體按照指定的對齊引數進行對齊
設定對齊引數可在結構體struct之前加上#pragma pack(對齊數),在struct之後加上#pragma pack;便可以設定對齊引數
如何知道結構體中某個成員相對於結構體起始位置的偏移量
我們可以使用這個#define offsetof(s,a) (size_t) (((s*)0)->a),這個用法就是我們告訴編譯器有一個指標指向結構體s,而它的值是0,然後我們取結構體中的a,a的地址就是a的偏移量了。
#include<iostream>
#include<cstdlib>
using namespace std;
#define offsetof(s,a) (size_t) &(((s*)0)->a)
struct a{
int m;
char n;
double c;
};
#pragma pack(4)
struct b{
char o;
double p;
int j;
};
#pragma pack;
int main()
{
cout <<"a的記憶體大小為"<< sizeof(a) << endl;
cout <<"b的記憶體大小為"<< sizeof(b) << endl;
cout << offsetof(b, p) << endl;
system("pause");
}