簡析結構體儲存分配

2021-08-06 03:10:09 字數 2776 閱讀 4716

結構與陣列類似,但是兩者之間存在著很大的差別。陣列是通過下標進行訪問,而結構是通過其成員的名字進行訪問的。其次結構體內部成員更加靈活,那麼結構體在記憶體中的儲存是怎麼分配的?

來看下面**:

#include struct s1

;struct s2

;int main()

程式執行結果為:

關於這段**中的結構體內存分配,看下圖:

我們可以通過

巨集offsetof來驗證一下,結構體成員在記憶體中的分配是否如上圖所示.

#define offsetof(struct_t,member) ((

size_t

)(char

*)&((struct_t *)0)->member)

offsetof返回的是結構體成員在結構體內存中的偏移量。

其函式原型在msdn中為下:

看**如下:

#include #includestruct s1 

;struct s2

;int main()

程式執行結果為:

這個即說明:

1. 結構體的第乙個成員在與結構體變數偏移量為0的位址處。

2. 結構體在記憶體中儲存時會發生對齊,其對齊規則為:其他成員變數要對齊到對齊數的整數倍的位址處。

//對齊數 = 編譯器預設的乙個對齊數 與 該成員大小的較小值。(vs中預設對齊數的值為8,linux中的預設值為4)

再看下面**:

#include struct s

;int main()

此程式執行結果為多少呢?  

根據上面的規則來分析,a佔據前8個位元組,c佔據第9個位元組,d根據對齊佔據第13~16這4個位元組,e[2]佔據17~20這四個位元組。那麼結構體總大小應為20。然而結構卻不是如此。

此段**執行的結果為:24。也就是說在儲存完e[2]後,結構體又多佔據了四個位元組的空間。這是什麼情況?

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

而上面**中結構體最大對齊數為8,而最後算的為20,不是8的倍數,所以再多開闢4個位元組的空間,即24個位元組的空間。

了解了這個規則後,來看這個**:

#include struct s

;int main()

可以很容易的分析有:a佔據前四個位元組,c佔據第5個位元組,d佔據第9~12個位元組,e佔據第13~14個位元組,又因為此結構體最大對齊數為4,所以結構體大小要為四的倍數,即要再開闢兩個自己的空間,因此,此結構體空間大小為:16。

程式執行結果:

那麼如果結構體巢狀了,其記憶體又是如何分配的?

看**:

#include struct s1

;struct s2

;int main()

此段**執行結果如下:

分析,其在記憶體中的儲存如下:

則分析有:

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

如果結構體中包含了指標的話,其記憶體分配如下:

#include struct s1

;int main()

程式執行結果為:

分析,c佔據第乙個位元組,a佔據第5~8個位元組,而無論是int指標還是char指標都佔據了4個位元組。

所以: 結構體中包含指標,無論指標是何種型別,其佔據記憶體均為4個位元組(64位機器上8個位元組)。

關於結構體內存對齊的原因:

1、平台原因(移植原因):

不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。

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

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

以上即為對結構體儲存分配的簡單解析,如有不足,還請大家指出!

C C 結構體的儲存分配

結構體的大小怎麼計算,在乙個整型佔4個位元組,字元型佔1個位元組的機器裡,乙個包含乙個整型 兩個字元型的結構體型別佔的空間有多大?4 2 1 6?看看下面這段 你知道它的列印結果 整型4個位元組,字元1個位元組 結果會是6 6 6 8嗎?讓我們來看一下結果吧 你對了多少個?第乙個和第四個相信不會有人...

關於結構體的儲存分配

先看乙個例子 struct my t struct my t2 int tmain int argc,tchar argv 結果為 1245020 1245021 1245016 1244996 1245004 1245000 1244980 1244981 1244984812 83個結構體中的成...

結構體的儲存分配問題

struct align 那麼這樣的結構將會花費 個位元組 因為int 型別是占用了 個位元組的,char型別占用 個位元組,所以邊界對齊原則,需要 個位元組 但是我們實際用的是 個位元組的大小,這樣的話我們的儲存利用率是比較低的 所以我們的改進方法就是調整結構宣告的順序就可以了,讓那些對邊界要求最...