c c 中的記憶體對齊

2021-06-26 03:15:08 字數 1646 閱讀 1367

32位linux 下:

class a

char c1 ;

sizeof(a) == 1 而非 4,這點有點出乎意料!按照對齊要求,在32位環境中預設的對齊是按照4位元組來的,但是這裡似乎沒有表現出4位元組的對齊要求!class b這樣定義

class b

char c1 ;

short s1 ;

這個時候sizeof(b) == 4 而非 3 ,又體現出了4位元組對齊的準則,對齊像是有選擇性的!

其實對齊是在一定的條件下才會產生的,當類或者結構體中 data members 的型別長度不一致的時候才會產生對齊操作。這個對齊操作是編譯器來自動完成的,當然按多少個字

節對齊還是程式設計師本身能控制的!在程式的首行使用#pragma pack(n)或者在編譯的時候加上-fpack-struct=n (n代表安多少位元組對齊)即可改變對齊方式。

在class a中,只有一種型別的data member ,char型別的長度都是1,並沒有出現型別長度不一致的情況,所以不會出現對齊操作!但是對於class b則就不一樣了,short型別的

長度和char型別的長度是不一致的,這就觸發了編譯器的對齊操作,所以sizeof(b) == 4而非 3,以下這個例子可以佐證這個說法。

class c

char c1,c2,c3,c4 ;

char c5 ;

sizeof(c) == 5 class c五個成員都是char型別,型別長度一致,不觸發對齊操作。

既然知道了對齊操作的觸發條件,那麼按照4來對齊到底是什麼意思呢?class b的大小sizeof(b)==4,這個因對齊而產生的填充位元組被填充的位置有兩中情況。第一中情況:在

c1和s1之間填充了這個位元組,第二種情況:在s1之後填充這個位元組,而c1和s1之間是緊挨著的!    

程式輸出事實證明,填充是第一種情況下的填充!如下例:

class d

public:

char c1 ;

short s1 ;

&c1 == 0xbff23cfc

&s1 == 0xbff23cfe

從結果可以看出,0xbff23cfe - 0xbff23cfc == 1也就是說中間空了乙個位元組,不然的話,s1的位址應該從0xbff23cfd開始的。也就是說,對齊是按照物件或者結構體中 data

members 中型別長度最大的乙個來進行補齊操作的,注意這裡的型別指的是內建型別,比如int,char等!下面乙個例子是個佐證:

class e

char c1 ;

short s1 ;

char c2 ;

則sizeof(e) == 6而非8,但是預設的4位元組對齊這個4位元組貌似在對齊中沒起到什麼作用,其實預設4還是有作用的,一旦data members 中的型別長度超過了4 那麼就只按照4來

進行對齊處理比如double 就是8個位元組,但是程式不會按照最長的double來進行對齊操作而是按照4來進行對齊處理。下面是乙個佐證:

class f

double d1 ;

int i1 ;

sizeof(f) == 12 而不是16

所以對於對齊的長度可以這麼說:在類或者結構體的data members中型別長度如果有超過4(預設情況下)的,則按照4來進行對齊處理,如果沒有超過4的,則按照型別長度最大

的來處理!

C C 中記憶體對齊問題

我們通過幾個例子來全面搞懂c c 中的記憶體對齊問題。來看看下面的結構體大小分別是多大?假設均在32位機器上 struct a 這個相信大家都知道,由於變數都是char型別,對齊值為1,所以結構體大小為3。struct b 對齊值為4,結構體大小為 4 4 8。第乙個4為int,第二個4裡面包含乙個...

C C 記憶體對齊

一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...

C C 記憶體對齊

一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...