#include "stdafx.h"
#include
struct a
test_a;
struct b
test_b;
struct c
test_c;
struct d
test_d;
int main()
輸出的結果為24 16 6 32
對於這樣的乙個結果感到一些困惑,在網上查了相關的資料之後發現,原來是這樣的:
對於結構體a和結構體b,二者之間並無實質的區別,定義的變數都是一樣的,只是變數的定義先後順序不同,結果占用的儲存空間就不同。
這是因為在一般的預設情況下,為了方便結構體重元素的訪問和管理,當結構體重的元素的長度都小於處理器的位數時便以結構體中長度最長的資料元素作為對其單元。
即,結構體的長度是最長的資料元素的整數倍。如果結構體重存在長度大於處理器位數的元素,那麼就以處理器為數為單元對齊。
在結構體a中
struct a
test_a;
編譯器首先檢測所有的資料中最長的資料元素。這裡unsigned __int64 最大,他占用了8個位元組,然後第乙個變數 a 為 int 型只佔 4 個位元組,但是為了對齊其被補上了四個位元組 , 接著變數 b 在 變數 a 有效位置之後被放置,但是目前只有 4 個空閒的位元組,根本放不下變數 b ,於是編譯器就再申請了 8 位元組的空間大小,將變數 b 放在 4 個空閒位元組之後,也就是說變數 b 的起始位置在第九個位元組。由於變數 b 需要 8 個位元組所以沒有留給變數 c 任何的剩餘空間,於是變數 c 再次申請 8 個位元組的空間用於儲存自己,當然它本可以只申請 2 位元組的空前就行了,但是為了對齊他只能申請 8 位元組。那麼最後我們就可以看到如下圖所示的資料儲存結構:0
… …
… 8
… …
… 15
16 …
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
… …
… 通過以上的分析我們明白了結構體內部 ( 也可以引伸到類的內部! ) 成員變數的宣告順序並不是隨意的,尤其是在記憶體需求特別緊張的開發環境中。
對齊的目的和原理,計算
什麼是對齊,以及為什麼要對齊:
對齊的作用和原因:
各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。其他平 臺可能沒有這種情況, 但是最常見的是如果不按照適合其平台要求對資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為 32 位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出,而如果存放在奇位址開始的地方,就可能會需要2個讀週期,並對兩次讀出的結果的高低位元組 進行拼湊才能得到該int資料。顯然在讀取效
率上下降很多。這也是空間和時間的博弈。
對齊的演算法:
由於各個平台和編譯器的不同,現以本人使用的gcc version 3.2.2編譯器(32位x86平台)為例子,來討論編譯器對struct資料結構中的各成員如何進行對齊的。
設結構體如下定義:
struct a
;結構體a中包含了4位元組長度的int乙個,1位元組長度的char乙個和2位元組長度的short型資料乙個。所以a用到的空間應該是7位元組。但是因為編譯器要對資料成員在空間上進行對齊。
所以使用sizeof(strcut a)值為8。
現在把該結構體調整成員變數的順序。
struct b
;這時候同樣是總共7個位元組的變數,但是sizeof(struct b)的值卻是12。
下面我們使用預編譯指令#progma pack (value)來告訴編譯器,使用我們指定的對齊值來取代預設的。
#pragma pack (2)
struct c
;#pragma pack ()
sizeof(struct c)值是8。
修改對齊值為1:
#pragma pack (1)
struct d
;#progma pack ()
sizeof(struct d)值為7。
對於char型資料,其自身對齊值為1,對於short型為2,對於int,float,double型別,其自身對齊值為4,單位位元組。
這裡面有四個概念值:
1.資料型別自身的對齊值:就是上面交代的基本資料型別的自身對齊值。
2.指定對齊值:#progma pack (value)時的指定對齊值value。
3.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。
有了這些值,我們就可以很方便的來討論具體資料結構的成員和其自身的對齊方式。 有效對齊值n是最終用來決定資料存放位址方式的值,最重要。有效對齊n,就是表示「對齊在n上」,也就是說該資料的"存放起始位址%n=0".
C語言 結構體儲存空間分配
這兩天在看結構體,一直在琢磨結構體的儲存空間分配的問題,琢磨了半天總算明白了。和大家分享一下,希望能有所幫助。相信大家都知道結構體裡元素儲存要對齊吧,話雖是沒錯,只是這個 對齊 裡面包含了很多微妙的東西。首先詳細的給出結構體內存儲存空間分配的原則吧 編譯器按照成員列表順序乙個接乙個地給每個成員分配記...
c語言中結構體儲存空間確定
1.使用sizeof函式可以檢視變數型別或者對應的變數所佔的空間。在vc 6.0下實驗的結果程式及結果如下 2.結構型別的占用空間要符合對齊原則和節邊界值原則。比如 includestruct x1 struct x2 struct x3 int main 結果為 對齊原則 結構中變數的儲存以該變數...
C中結構體的儲存分配
對於c語言中結構體所佔的儲存空間的大小,也一直是筆試面試的常客,今天好好看了一下這方面,以前一直以為很清楚了,今天通過各種實際測試舉例,發現原來還是沒有搞透徹,好在現在是徹底懂了,所以和大家分享,希望能有所幫助。提到結構體,相信大家都知道 元素儲存要對齊 話是沒有錯,只是這個 對齊 裡面包含了很多微...