C中结构体的存储分配
生活随笔
收集整理的這篇文章主要介紹了
C中结构体的存储分配
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
對于C語言中結(jié)構(gòu)體所占的存儲(chǔ)空間的大小,也一直是筆試面試的常客,今天好好看了一下這方面,以前一直以為很清楚了,今天通過各種實(shí)際測試舉例,發(fā)現(xiàn)原來還是沒有搞透徹,好在現(xiàn)在是徹底懂了,所以和大家分享,希望能有所幫助。
提到結(jié)構(gòu)體,相信大家都知道元素存儲(chǔ)要對齊,話是沒有錯(cuò),只是這個(gè)“對齊”里面包含了很多微妙的東西。首先詳細(xì)的給出結(jié)構(gòu)體內(nèi)存分配的原則吧:編譯器按照成員列表順序一個(gè)接一個(gè)地給每個(gè)成員分配內(nèi)存。只有當(dāng)存儲(chǔ)成員時(shí)需要滿足正確的邊界對齊要求時(shí),成員之間才可能出現(xiàn)用于填充的額外內(nèi)存空間。接下來我們來慢慢理解這句話。 sizeof操作符能夠得出一個(gè)結(jié)構(gòu)的整體長度,包括因邊界對齊而跳過的那些字節(jié)。所以一般都用sizeof來計(jì)算其所占存儲(chǔ)空間。來看下面的例子: struct test1? { int a; char b[9]; char c; }; 計(jì)算可以得到test1占16個(gè)字節(jié)。原因是a占4個(gè)字節(jié)(32位機(jī),int占4個(gè)字節(jié)),b和c分別占9個(gè)字節(jié)和1個(gè)字節(jié),加起來10個(gè)字節(jié),與a對齊,則需要12個(gè)字節(jié),所以總共需要16個(gè)字節(jié)。這個(gè)例子就是我們最熟悉的,接下來看一下個(gè)。 struct test2? { char b[9]; int a; char c; }; 計(jì)算可以得到test2占20個(gè)字節(jié)。比較test1和test2可以發(fā)現(xiàn)僅僅將a和b的位置換了一下,為什么結(jié)果會(huì)不同呢?這就是前面定義中所說的順序的問題。int為最大字節(jié),一開始分配9個(gè)字節(jié),然后是a,為了對齊,這時(shí)候應(yīng)該是12+4個(gè)字節(jié),后面又來一個(gè)char,為了對齊加4,所以總共是20個(gè)字節(jié)。而test1因?yàn)楹竺鎯蓚€(gè)類型一致,所以可以和在一起分配,然后對齊。 接下來我們在加大難度,看如下例子: struct test3? { char b[9]; int a; char c; double d; }; 按照上面的邏輯,b占9個(gè)字節(jié),a占4個(gè)字節(jié),為了和a對齊,所以此時(shí)應(yīng)該是12+4,接著是c為1個(gè)字節(jié)總共為12+4+1=17,然后是d為8個(gè)字節(jié),為了和8字節(jié)對齊,則應(yīng)該為24+8=32個(gè)字節(jié),即最終結(jié)果為32個(gè)字節(jié)。變換一下順序,得到如下例子: struct test4? { char b[9]; int a; double d; char c; }; 同樣的,b和a占據(jù)12+4個(gè)字節(jié),d為8個(gè)字節(jié),則應(yīng)該是16+8=24,加上最后的一個(gè)字節(jié),為了對齊,總共也是24+8=32個(gè)字節(jié)。這里需要注意的是,若數(shù)組b元素改為13,則為了對齊,d前面應(yīng)該是16+4,然后遇到d,對齊后為24+8,在加上最后的8個(gè)字節(jié),應(yīng)該為40個(gè)字節(jié)。 再來看一個(gè): struct test4? { double d; char b[9]; int a; char c; }; d占8個(gè)字節(jié),b占9個(gè)字節(jié),后面是int,為了對齊,加上a應(yīng)該是20+4,再加上1個(gè)字節(jié),為了和最大的double對齊,所以應(yīng)該是20+4+8=32個(gè)字節(jié)。 好了,通過列舉這么多不同的例子,最終目標(biāo)只有一個(gè),是真的搞清楚某個(gè)結(jié)構(gòu)體占據(jù)的空間大小。通過上面的例子,我總結(jié)了以下幾點(diǎn)。 1)首先,看該結(jié)構(gòu)體中最大的“基元素”(這是我杜撰的,就是說基本元素類型最大的是哪個(gè),例如test1和test2都是int,而test3和test4都是double,而不是看數(shù)組總共所占據(jù)的大小),找到這個(gè)以后,結(jié)構(gòu)體所占據(jù)的空間的大小一定要是該基本元素所占空間大小的整數(shù)倍。 2)接著,按順序?qū)⒃剡M(jìn)行排列。前一元素要與后一元素對齊,如果后一元素的“基元素”比前一個(gè)大,則前一元素需要調(diào)整大小,即對齊該后一元素。 3)最后將得到的字節(jié)大小加起來,跟最大的基元素對齊,即得到最終的所占存儲(chǔ)空間大小。 如果要確定結(jié)構(gòu)中某個(gè)成員的實(shí)際位置,可以使用offsetof宏(stddef.h)offsetof(type,member)。type是結(jié)構(gòu)的類型,member是該結(jié)構(gòu)的成員名,表達(dá)式的結(jié)構(gòu)是一個(gè)sizeof_t值。表示該指定成員的存數(shù)位置(離該結(jié)構(gòu)體存儲(chǔ)的起始位置)。 另外還有一點(diǎn)值得一提的是,當(dāng)結(jié)構(gòu)體里面包含另一結(jié)構(gòu)體時(shí),直接將該結(jié)構(gòu)體中的內(nèi)容代換進(jìn)去,計(jì)算其總的存儲(chǔ)空間即可。總結(jié)
以上是生活随笔為你收集整理的C中结构体的存储分配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前沿 | 美国白宫AI峰会闭幕:特朗普政
- 下一篇: 通过 html5 FileReader