天天看點

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的記憶體空間是這樣的:

C++記憶體對齊總結

記憶體配置設定過程:

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

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

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

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

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

C++記憶體對齊總結

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;
}      

輸出:

C++記憶體對齊總結

可以看到,當我們把編譯器的記憶體分割大小設定為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/

*/