1. 程式人生 > >C++記憶體對齊總結【轉載】

C++記憶體對齊總結【轉載】

大家都知道,C++空類的記憶體大小為1位元組,為了保證其物件擁有彼此獨立的記憶體地址。非空類的大小與類中非靜態成員變數和虛擬函式表的多少有關。

而值得注意的是,類中非靜態成員變數的大小與編譯器記憶體對齊的設定有關。

成員變數在類中的記憶體儲存並不一定是連續的。它是按照編譯器的設定,按照記憶體塊來儲存的,這個記憶體塊大小的取值,就是記憶體對齊。

 一、引入問題。

複製程式碼

#include<iostream>
using namespace std;
class test {
private :
    
    char c='1';//1byte 
    int i;//4byte
    short s=2;//2byte
};

int main(){
    cout << sizeof(test) << endl;
    return 0;
}

複製程式碼

輸出:12

複製程式碼

class test2 {
private:
    int i;//4byte
    char c = '1';//1byte 
    short s = 2;//2byte
};

int main(){
    cout << sizeof(test2) << endl;
    return 0;
}

複製程式碼

 輸出:8

我們可以看到。類test和test2的成員變數完全一樣,只是定義順序不一樣,卻造成了2個類佔用記憶體大小不一樣。而這就是編譯器記憶體對齊的緣故。

二、規則

1、第一個資料成員放在offset為0的地方,以後每個資料成員的對齊按照#pragma pack指定的數值和這個資料成員自身長度中,比較小的那個進行。

2、在資料成員完成各自對齊之後,類(結構或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大資料成員長度中,比較小的那個進行。

  很明顯#pragma pack(n)作為一個預編譯指令用來設定多少個位元組對齊的。值得注意的是,n的預設數值是按照編譯器自身設定,一般為8,合法的數值分別是1、2、4、8、16。

  即編譯器只會按照1、2、4、8、16的方式分割記憶體。若n為其他值,是無效的。

三、問題分析

(1)對於類test的記憶體空間是這樣的:

記憶體分配過程:

1、char和編譯器預設的記憶體預設分割大小比較,char比較小,分配一個位元組給它。

2、int和編譯器預設的記憶體預設分割大小比較,int比較小,佔4位元組。只能空3個位元組,重新分配4個位元組。

3、short和編譯器預設的記憶體預設分割大小比較,short比較小,佔2個位元組,分配2個位元組給它。

4、對齊結束類本身也要對齊,所以最後空餘的2個位元組也被test佔用。

(2)對於類test2的記憶體空間是這樣的:

1、int和編譯器預設的記憶體預設分割大小比較,int比較小,佔4位元組。分配4個位元組給int。

2、char和編譯器預設的記憶體預設分割大小比較,char比較小,分配一個位元組給它。

3、short和編譯器預設的記憶體預設分割大小比較,short比較小,此時前面的char分配完畢還餘下3個位元組,足夠short的2個位元組儲存,所以short緊挨著。分配2個位元組給short。

4、對齊結束類本身也要對齊,所以最後空餘的1個位元組也被test佔用。

(3)使用#pragma pack(n)

複製程式碼

#include<iostream>
using namespace std;
#pragma pack(1)//設定為 1 位元組對齊
class test {
private :
    
    char c='1';//1byte 
    int i;//4byte
    short s=2;//2byte
};

class test2 {
private:
    int i;//4byte
    char c = '1';//1byte 
    short s = 2;//2byte
};
int main(){
    cout << sizeof(test) << endl;
    cout << sizeof(test2) << endl;
    return 0;
}

複製程式碼

輸出:

可以看到,當我們把編譯器的記憶體分割大小設定為1後,類中所有的成員變數都緊密的連續分佈。

至此,C++記憶體對齊總結已經差不多了。想要更多瞭解C++物件記憶體分配推薦陳浩的2篇文章:

http://blog.csdn.net/haoel/article/details/3081328

和http://blog.csdn.net/haoel/article/details/1948051

陳浩大神寫的太透徹了。

參考:http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html

http://www.jb51.net/article/45406.htm

/**
*   ————————如果覺得本博文還行,別忘了推薦一下哦,謝謝!
*   作者:錢書康
*   歡迎轉載,請保留此段宣告。
*   出處:http://www.cnblogs.com/zrtqsk/ 
*/