結構體內存對齊

2021-08-24 23:36:54 字數 2024 閱讀 1891

先來看幾個例題:

例1:

struct s1

;printf("%d\n", sizeof(struct s1));

解析:

char 為1個位元組, int 為4個位元組;

char c1 從0偏移開始,占用乙個位元組;現在可用偏移為1偏移,接下來存放 int i ,1不是對齊數4 的整數倍,所以向後繼續偏移一直到4,4是對齊數4的整數倍,所以將int i 存放在偏移位址為4處,占用4個位元組;現在可用偏移變成8,存放 char c2 ,佔乙個位元組,現處於9偏移。9不是最大對齊數4的整數倍,所以向後繼續偏移直到偏移處為12的地方。如下圖所示:

所以,該結構體的大小為 1+3+4+1=9+3=12

例2:

struct s2

;printf("%d\n", sizeof(struct s2));

解析:

double 佔8個位元組, char 佔乙個位元組,int 佔4個位元組;

double d 從0處開始偏移,占用8個位元組;現在可用偏移為8偏移,接下來存放 char c ,8是對齊數1的倍數,所以char c 存放在偏移位址為8處,占用乙個位元組;現在可用偏移變成9,接下來存放 int i ,9不是對齊數4的倍數,所以繼續向後偏移到12,12是對齊數4的倍數,所以將 int i 存放在偏移位址為12處,占用4個位元組,現處於16偏移,是最大對齊數8的倍數。如下圖所示:

所以,結構體的大小為 8+1+3+4=16

例3:結構體巢狀問題

struct s3

;printf("%d\n", sizeof(struct s3));

解析:

char 佔乙個位元組,struct s2 s2 為例2 的結構體,佔16個位元組,double 佔8個位元組;

char c1 從0處開始偏移,占用乙個位元組;現在可用偏移為1偏移;接下來存放struct s2 s2 ,1不是對齊數8的整數倍,所以繼續向後偏移到8,8是對齊數8 的倍數,所以將結構體s2存放到8偏移處,占用16個位元組;現在可用偏移為8+16=24,24是對齊數8的整數倍,所以將 double d 存放到當前的24偏移處,占用8個位元組,現處於24+8=32偏移處,32是最大對齊數8的整數倍。如下圖所示:

所以,結構體的大小為 1+7+16+8=32

結構體內存對齊規則:第乙個成員在與結構體變數偏移量為0的位址處。

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

對齊數 = min(編譯器預設的乙個對齊數 ,該成員大小)vs 中預設的值為 8

linux 中預設的值為 4

結構體總大小為最大對齊數(每個成員變數除了第乙個成員,都有乙個對齊數)的整數倍。

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

結構體的對齊數為結構體當中所有對齊數中的最大對齊數。

為什麼存在記憶體對齊?

效能原因:

資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。

原因在於,為了訪問未對齊的記憶體,處理器需要做兩次記憶體訪問;而對齊的記憶體訪問僅需一次訪問。

總的來講:結構體的記憶體對齊是拿空間來換取時間的做法。

結構體內存對齊

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

結構體內存對齊

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

結構體內存對齊

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