結構體內存對齊

2021-09-20 17:02:12 字數 3078 閱讀 5701

結構是乙個或多個變數的集合,這些變數可能為不同的型別,為了處理的方便而將這些變數組織在乙個名字之下;

下面先來看乙個定義結構體的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include

#include

structtesttype;

intmain()

在該結構體中定義了乙個char型別的變數first,乙個int型別的變數second和乙個double型別的變數third;在vs2013下進行編譯執行得到如下結果

按照我的理解char變數佔乙個位元組,那麼int的位址就是mytest+1。但從執行結果來看,int的位址卻是成了mytest+4。此時我就想到「記憶體對齊",記憶體對齊指的是:

那麼為什麼上面程式的執行結果會是這個樣子?先簡單介紹一下記憶體對齊的原因:

平台原因:不是所有的硬體平台都能訪問任意位址上的任意的資料,某些平台只能在某些地方讀取某些資料,否則會丟擲硬體異常。

效能原因:資料結構(尤其是棧)應該盡可能的在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問;而對齊的記憶體訪問只需要一次(經過記憶體對齊後,cpu訪問記憶體的速度會大大提高)。

對原因2進行解釋:

cpu把記憶體看成是一塊一塊的,以2(short),4(int),8(double)為單位進行讀取的。簡單舉乙個例子:

假設cpu要讀取乙個4位元組大小的資料到暫存器中,分兩種情況討論:

資料從0位元組開始;

資料從1位元組開始;

兩種情況如圖所示:

當cpu從0位元組開始讀取的時候,只需要讀取一次即可把4位元組的內容讀取到暫存器中;當cpu從1位元組開始讀取的時候,顯然問題開始變得複雜,因為此時資料不再記憶體讀取邊界上,這是一類記憶體未對齊的資料。

此時記憶體先訪問一次記憶體,讀取0-3位元組資料到暫存器,並且再次讀取4-7位元組資料到暫存器中,接著把0位元組和6,7,8位元組的內容刪掉,然後合併1,2,3,4,位元組的內容3暫存器,顯然相比第一種情況而言,cpu進行了很多額外的操作,大大降低了cpu的效能。

結構體對齊規則

1.

第乙個成員在結構體變數偏移量為

0的位址處;

2.

其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處;

//

對齊數= 

編譯器預設的乙個對齊數與該成員的較小值;

vs

中預設的值為8;

linux

中的預設值為4;

3

.結構體總大小為最大對齊數(每個變數除了第乙個成員都有乙個對齊數,不包含預設對齊數的     整數倍;

4.

如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體     大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

下面開始分析本文開頭時的**:

在結構體testtype中最大資料成員的長度是8位元組,以8位元組為對齊係數,first佔1位元組,後面會有7位元組的空間,編譯器會填充3位元組,second佔4位元組,所以second會填充到first後面,third佔8位元組,因此mytest的大小是4+4+8=16位元組。

分析上面結構體資料成員的位址,根據位址我們顯然可以得出此結果完全符合上面的分析。

調整文章開頭結構體裡面的變數順序;

1

2

3

4

5

6

structtesttype

並將該程式在vs2013下執行,輸出結果:

1

2

3

4

mytest位址是:bcfac8

char變數位址是:bcfac8

double變數位址是:bcfad0

int變數位址是:24

分析上面**:

在結構體testtype中最大資料成員的長度是8位元組,以8位元組為對齊係數,first佔1位元組,後面會有7位元組的空間,double佔8位元組,編譯器會填充char後面的7位元組空間,int佔4位元組,編譯器會將其填充到8位元組,所以mytest的大小是3*8=24位元組。

分析上面結構體資料成員的位址,根據位址我們顯然可以得出此結果完全符合上面的分析。

結構體內存對齊

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

結構體內存對齊

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

結構體內存對齊

對齊規則 每個特定平台上的編譯器都有自己的預設 對齊係數 也叫對齊模數 程式設計師可以通過預編譯命令 pragma pack n n 1,2,4,8,16來改變這一係數,其中的n就是你要指定的 對齊係數 規則 1 資料成員對齊規則 結構 struct 的資料成員,第乙個資料成員放在offset為0的...