關於c 中記憶體對齊的一些問題

2021-09-29 06:33:21 字數 1520 閱讀 2552

假設有以下**:

#include

#include

class a;

class b;

int main()

原始碼檔案為test.cpp,在64位機器上編譯執行

#g++ test.cpp -o test

#./test

int是4個位元組,short2個位元組,char1個位元組,理論上a因該是4*2+2+1=11個位元組啊,為啥是12呢,實際上可以這樣理解,

記憶體是4個位元組一塊,對於class a, a佔4個,b和c佔4個位元組,d佔4個位元組,一共12個位元組,b和c佔的那4個位元組中雖然有乙個位元組沒有利用,但是也不能存下d,需要額外再搞4個位元組。

對於class b, double在64位機器上是8個位元組,所以是e8個位元組,f4個位元組,g和h4個位元組,一共16個位元組。

有趣的是如果我們調整一下a和b中變數的順序,得出的結果也不一樣,所以上述思路還有問題。

例如class a;

class b;

那麼輸出結果又變了

實際上,仔細想想,還是那個道理,就是記憶體中4個位元組是一塊,對於class a,a佔4個位元組,b佔四個位元組,d佔4個位元組,c佔4個位元組,雖然浪費了5個位元組,但是前乙個變數沒有利用的位元組,也不能放下後乙個變數。

按照這個理論,class b應該是佔20個位元組啊,怎麼又是24呢,我們可以這麼想,既要4位元組對齊,又要8位元組,e佔8個位元組,g和f佔8個位元組,h佔8個位元組,一共24個位元組。而上面的class b是e8個位元組,f,g,h佔8個位元組,一共16個位元組。

我們還可以修改一下程式,進一步驗證猜想,例如:

class a;

class b;

我們按照從小到大去排列變數,那麼結果又是怎樣呢。

class a是:a和b佔4個位元組,c,d各4個位元組,一共12;class b e,f,g佔8個位元組,h8個位元組,一共16。由此可見,我們可以得到兩個明顯的規律;

1.如果變數的大小不超過int,那麼就是4位元組對齊。(有待驗證)

2.如果有double long, 那麼就需要8個位元組對齊。

對於1,我們修改一下程式:

class a;

class b;

那麼結果是這樣的

實際上,如果類中只用乙個char變數,那麼它的大小只有1,而不是4。

對程式再次修改

class a;

class b;

那麼結果又是怎樣呢。

再次修改程式

class a;

class b;

結果是這樣的:

由此可見,在分配記憶體的時候,是以類中最長的那個變數型別作為對齊標準的,而不是int,可以是1(char),2(short), 4(int), 8(long, double),此外,如果結構體中即有double又有int,那麼還要考慮4位元組對齊,比如

class b;

占用的是24位元組,而不是16位元組,儘管8個位元組可以存下g,f,h. 

測試用的平台是ubuntu12.01鍵入uname --m輸出x86_64,作業系統是 64位,gcc版本是4.7。

c 中關於記憶體的一些問題

void getmemory char p void test void 請問執行test函式會有什麼樣的結果?答 程式崩潰。因為getmemory並不能傳遞動態記憶體,test函式中的str一直都是null。strcpy str,helloworld 將使程式崩潰。解析 該函式中的p是乙個臨時的指...

關於位元組對齊的一些問題

寫在前面,博主也是個菜鳥,只是在這裡分享一些自己遇到的問題,如有表述不當的地方請諒解。關於位元組對齊的問題其實很好理解,只要了解下cpu讀取資料的細節再動手實踐一下就一目了然了,下面是我了解到的cpu讀取資料時的一些細節和實踐的過程。首先看一下記憶體的排列 注釋 數字時位址,每格表示一位元組的位址。...

關於記憶體溢位的一些問題

不知道是否理解正確,還請高手多加指點,這是我今天再修改程式的時候碰到的一些問題,在我修改的軟體當中正是通過類似 sum函 數的指標返回值,程式編譯沒有錯誤,在我反覆試驗軟體的功能時候出現了指標錯誤,後來修改了函式,讓其不通過指標返回值,這才得以不出現指標錯誤,但在內 存溢位檢測過程中,發現軟體當中的...