對於c語言中結構體所佔的儲存空間的大小,也一直是筆試面試的常客,今天好好看了一下這方面,以前一直以為很清楚了,今天通過各種實際測試舉例,發現原來還是沒有搞透徹,好在現在是徹底懂了,所以和大家分享,希望能有所幫助。
提到結構體,相信大家都知道
元素儲存要對齊
,話是沒有錯,只是這個「
對齊」裡面包含了很多微妙的東西。首先詳細的給出結構體內存分配的原則吧:
編譯器按照成員列表順序乙個接乙個地給每個成員分配記憶體。只有當儲存成員時需要滿足正確的邊界對齊要求時,成員之間才可能出現用於填充的額外記憶體空間
。接下來我們來慢慢理解這句話。
sizeof操作符能夠得出乙個結構的整體長度,包括因邊界對齊而跳過的那些位元組。所以一般都用sizeof來計算其所佔儲存空間。來看下面的例子:
struct test1 ;
計算可以得到test1佔16個位元組。原因是a佔4個位元組(32位機,int佔4個位元組),b和c分別佔9個位元組和1個位元組,加起來10個位元組,與a對齊,則需要12個位元組,所以總共需要16個位元組。這個例子就是我們最熟悉的,接下來看一下個。
struct test2 ;
計算可以得到test2佔20個位元組。比較test1和test2可以發現僅僅將a和b的位置換了一下,為什麼結果會不同呢?這就是前面定義中所說的順序的問題。int為最大位元組,一開始分配9個位元組,然後是a,為了對齊,這時候應該是12+4個位元組,後面又來乙個char,為了對齊加4,所以總共是20個位元組。而test1因為後面兩個型別一致,所以可以和在一起分配,然後對齊。
接下來我們在加大難度,看如下例子:
struct test3 ;
按照上面的邏輯,b佔9個位元組,a佔4個位元組,為了和a對齊,所以此時應該是12+4,接著是c為1個位元組總共為12+4+1=17,然後是d為8個位元組,為了和8位元組對齊,則應該為24+8=32個位元組,即最終結果為32個位元組。變換一下順序,得到如下例子:
struct test4
;同樣的,b和a佔據12+4個位元組,d為8個位元組,則應該是16+8=24,加上最後的乙個位元組,為了對齊,總共也是24+8=32個位元組。這裡需要注意的是,若陣列b元素改為13,則為了對齊,d前面應該是16+4,然後遇到d,對齊後為24+8,在加上最後的8個位元組,應該為40個位元組。
再來看乙個:
struct test4
;d佔8個位元組,b佔9個位元組,後面是int,為了對齊,加上a應該是20+4,再加上1個位元組,為了和最大的double對齊,所以應該是20+4+8=32個位元組。
好了,通過列舉這麼多不同的例子,最終目標只有乙個,是真的搞清楚某個結構體佔據的空間大小。通過上面的例子,我總結了以下幾點。
1)首先,看該結構體中最大的「基元素」(這是我杜撰的,就是說基本元素型別最大的是哪個,例如test1和test2都是int,而test3和test4都是double,而不是看陣列總共所佔據的大小),找到這個以後,結構體所佔據的空間的大小一定要是該基本元素所佔空間大小的整數倍。
2)接著,按順序將元素進行排列。前一元素要與後一元素對齊,如果後一元素的「基元素」比前乙個大,則前一元素需要調整大小,即對齊該後一元素。
3)最後將得到的位元組大小加起來,跟最大的基元素對齊,即得到最終的所佔儲存空間大小。
如果要確定結構中某個成員的實際位置,可以使用offsetof巨集(stddef.h)offsetof(type,member)。type是結構的型別,member是該結構的成員名,表示式的結構是乙個sizeof_t值。表示該指定成員的存數字置(離該結構體儲存的起始位置)。
另外還有一點值得一提的是,當結構體裡面包含另一結構體時,直接將該結構體中的內容代換進去,計算其總的儲存空間即可。
C中結構體的儲存分配
對於c語言中結構體所佔的儲存空間的大小,也一直是筆試面試的常客,今天好好看了一下這方面,以前一直以為很清楚了,今天通過各種實際測試舉例,發現原來還是沒有搞透徹,好在現在是徹底懂了,所以和大家分享,希望能有所幫助。提到結構體,相信大家都知道元素儲存要對齊,話是沒有錯,只是這個 對齊 裡面包含了很多微妙...
C語言結構體的儲存分配
若結構體裡面包含多種資料型別,其如何在記憶體中分配儲存空間呢?編譯器在處理結構體空間分配時,採取的是對齊方式,按照結構體中成員中成員型別位元組數最大的為標準,從上往下對結構體成員進行賦值,若當前成員的位元組數小於最大成員位元組數,接著為下乙個連續分配記憶體,若下乙個的記憶體分配後會大於最大成員位元組...
C語言 結構體儲存空間分配
這兩天在看結構體,一直在琢磨結構體的儲存空間分配的問題,琢磨了半天總算明白了。和大家分享一下,希望能有所幫助。相信大家都知道結構體裡元素儲存要對齊吧,話雖是沒錯,只是這個 對齊 裡面包含了很多微妙的東西。首先詳細的給出結構體內存儲存空間分配的原則吧 編譯器按照成員列表順序乙個接乙個地給每個成員分配記...