1. 程式人生 > >C++之#progma pack預處理

C++之#progma pack預處理

       前文我們簡單地介紹了一下C\C++中的預處理,現在我們再來了解一下#progma pack的使用方法。

        #progma pack ([n])表示記憶體對齊,目的是為了優化記憶體,減少記憶體碎片,使得記憶體按照一個固定的規則進行分配,讓分配的記憶體總是n的倍數,避免隨意分配記憶體大小。舉個例子,我們在Visual C++中編寫如下的類,

class X 
{ 
    int a; 
    char b; 
    short c; 
};

那麼sizeof(X)等於多少?有人會說,很簡單,sizeof(X)=4+1+2=7。有這種想法的朋友不妨到Visual C++中去試一試;認為sizeof(X)等於8的朋友,恭喜你們答對了,下面我們簡單的分析一下原因。在Visual C++中有起始地址對齊的倍數規則,內容是各成員變數存放的起始地址相對於結構的起始地址的偏移量必須為改變數的型別所佔位元組數的倍數。如下圖所示,

visual C

圖1 分配方式的對比

從圖1中,我們可以看出,a和b的分配方式是相同的。根據起始地址對齊的倍數規則,如果c的偏移量為5,而c所佔位元組數為2,所以c的起始地址不能是5,而是6。

        我們回過頭來,說說progma pack吧。progma pack有兩個規則:對齊長度規則和圓整規則。

1)對齊規則

        結構、聯合體或者類的資料成員的第一個放在偏移量為0的地方,以後每一個數據成員的對齊按照#progma pack制定的數值和這個資料成員的型別長度中取比較小的哪個值進行對齊。

        例如#progma pack(4),使用上一例的Class X,那麼sizeof(X)=8,根據對齊規則,按照指定的數值長度(4)和c的資料型別長度(2)中取較小者,那就是2,於是c按照2的倍數來對齊,也就是起始地址為6的位置。

2)圓整規則

        在宣告#progma pack(n)的情況下,整個資料型別的長度必須為n的倍數。例如我們編寫如下的類Y,

class Y 
{ 
    int a; 
    char b; 
    short c; 
    char d; 
};

那麼正常情況下,以及在對齊規則和圓整規則下記憶體分配方式如圖2所示。

progma pack

圖2 對齊規則和圓整規則

        經過簡單地講解,我想大家應該清楚#progma pack的作用了,那各位晚安了,好睏呀……