對資料對齊的探索

2021-04-08 16:23:42 字數 1883 閱讀 4007

有如下的兩個結構體:

struct astruct b

; };

那麼sizeof(a)

和sizeof(b)

一樣嗎?讓我在編譯器裡試一下,啊

?怎麼不一樣?兩個結構體明明相同,只是第二和第三個成員變數的位置顛倒了結果卻大相徑庭。到底是因為什麼呢?

答案是編譯器的資料對齊方式在作怪。以

vc6.0

為例,預設情況下的對其方式是

8位。所以

struct a

的大小為24,

struct b

的大小為

16,下面就具體分析一下資料空間占用情況。 在

struct a中的,

編譯器首先檢測所有的成員變數中的

size

最大值。很顯然

unsigned __int64

最大,sizeof(unsigned __int64)為8

,然後第乙個變數a為

int型只佔

4個位元組,但是為了對齊其被補上了四個位元組

,接著變數b在

變數a

有效位置之後被放置,但是目前只有

4個空閒的位元組,根本放不下變數

b,於是編譯器就再申請了

8位元組的空間大小,將變數b放在

4個空閒位元組之後,也就是說變數

b的起始位置在第九個位元組。由於變數b需要

8個位元組所以沒有留給變數

c任何的剩餘空間,於是變數

c再次申請

8個位元組的空間用於儲存自己,當然它本可以只申請

2位元組的空前就行了,但是為了對齊他只能申請

8位元組。那麼最後我們就可以看到如下圖所示的資料儲存結構: 0

8

15

23

a

多申請的空間 b

c

多申請的空間

struct b

中的,

編譯器前幾步的處理也和

struct a

的一樣,直到該處理變數

c 時,編譯器依然要先看看為變數

a分配的空間是否還有多餘並且多餘的空間是否足以容納下變數

c,由於變數

c只需要兩個位元組,而a卻有

4個位元組的剩餘空間,所以變數

c就很輕鬆的被放置在

a之後的

4個位元組內而不需要再申請空間。變數

b依然申請

8位元組的空間並跟隨在變數

a空餘空間之後。最後我們就可以看到如下圖所示的資料儲存結構: 0

1

2

3

4

5

6

7

8

15

a

c

多申請的空間

b

通過以上的分析我們明白了結構體內部

(也可以引伸到類的內部!

)成員變數的宣告順序並不是隨意的,尤其是在記憶體需求特別緊張的開發環境中。

C 二) 對陣列指標以的探索

include using namespace std int main int array 10 int i 1 int size sizeof int cout array i 的指標 array 1 endl cout array 我們的目的是觀察以下指標的值 1,array 1 的指標 2,...

資料的對齊

linux沿用的對齊策略是2位元組資料型別 例如 short 的位址必須是2的倍數,而較大的資料型別 例如 int int float 和 double 的位址必須是4的倍數。注意,這個要求就意味著乙個short型別物件的位址的最低位必須等於0。類似地,任何 int 型別的物件或指標的位址的最低兩位...

對資料定義的認識

sql中的ddl包括定義模式,域,關係,檢視,索引,斷言,授權等。一 sql的資料型別 有內建資料型別和使用者自定義的資料型別。乙個函式 etract filed from var 從var中提取欄位filed。二 模式的定義和刪除 模式就相當於資料庫。dbms為關係的命名提供了乙個3級層次結構,乙...