1. 程式人生 > >C/C++ struct/class/union記憶體對齊

C/C++ struct/class/union記憶體對齊

轉自:http://www.cnblogs.com/biyeymyhjob/archive/2012/09/07/2674992.html

struct/class/union記憶體對齊原則有四個:

1).資料成員對齊規則:結構(struct)(或聯合(union))的資料成員,第一個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是陣列,結構體等)的整數倍開始(比如int在32位機為4位元組, 則要從4的整數倍地址開始儲存),基本型別不包括struct/class/uinon。

2).結構體作為成員:如果一個結構裡有某些結構體成員,則結構體成員要從其內部"最寬基本型別成員"的整數倍地址開始儲存.(struct a裡存有struct b,b裡有char,int ,double等元素,那b應該從8的整數倍開始儲存.)。

3).收尾工作:結構體的總大小,也就是sizeof的結果,.必須是其內部最大成員的"最寬基本型別成員"的整數倍.不足的要補齊.(基本型別不包括struct/class/uinon)。

4).sizeof(union),以結構裡面size最大元素為union的size,因為在某一時刻,union只有一個成員真正儲存於該地址。

例項解釋:下面以class為代表

No.1

複製程式碼
class Data
{
    char c;
    int a;
};
 
cout << sizeof(Data) << endl;
複製程式碼

No.2

複製程式碼
class Data
{
    
char c; double a; }; cout << sizeof(Data) << endl;
複製程式碼

顯然程式No.1 輸出的結果為 8    No.2 輸出的結果為 16 .

No.1最大的資料成員是4bytes,1+4=5,補齊為4的倍數,也就是8。而No.2為8bytes,1+8=9,補齊為8的倍數,也就是16。

No.3

複製程式碼
class Data
{
    char c;
    int a;
    char d;
};
 
cout << sizeof(Data) << endl;
複製程式碼

No.4

複製程式碼
class
Data { char c; char d; int a; }; cout << sizeof(Data) << endl;
複製程式碼


No.3執行結果為 12  No.4執行結果為 8

class中的資料成員放入記憶體的時候,記憶體拿出一個記憶體塊來,資料成員們排隊一個一個往裡放,遇到太大的,不是把自己劈成兩半,能放多少放多少,而是等下一個記憶體塊過來。這樣的話,就可以理解為什麼No.3,No.4兩端的程式碼輸出結果不一樣了,因為左邊是1+(3)+4+1+(3)=12,而右邊是1+1+(2)+4=8。括號中為補齊的bytes。

No.5

複製程式碼
class BigData
{
    char array[33];
};
 
class Data
{
    BigData bd;
    int integer;
    double d;
};
 
cout << sizeof(BigData) << "   " << sizeof(Data) << endl;
複製程式碼

No.6

複製程式碼
class BigData
{
    char array[33];
};
 
class Data
{
    BigData bd;
    double d;
};
 
cout << sizeof(BigData) << "   " << sizeof(Data) << endl;
複製程式碼

No.5和No.6執行結果均為: 48

在預設條件下,記憶體對齊是以class中最大的那個基本型別為基準的,如果class中有自定義型別,則遞迴的取其中最大的基本型別來參與比較。在No.5和No.6中記憶體塊一個接一個的過來接走資料成員,一直到第5塊的時候,BigData裡只剩1個char了,將它放入記憶體塊中,記憶體塊還剩7個bytes,接下來是個int(4bytes),能夠放下,所以也進入第5個記憶體塊,這時候記憶體塊還剩3bytes,而接下來是個double(8bytes),放不下,所以要等下一個記憶體快到來。因此,No.5的Data的size=33+4+(3)+8=48,同理No.6應該是33+(7)+8=48。

順便提一下Union: 共用體表示幾個變數共用一個記憶體位置,在不同的時間儲存不同的資料型別和不同長度的變數。在union中,所有的共用體成員共用一個空間,並且同一時間只能儲存其中一個成員變數的值。