有如下的兩個結構體:
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級層次結構,乙...