C語言中 struct成員變數順序對記憶體的佔用

YunShell發表於2013-08-29

          在C語言的結構體中,是會按照其變數型別來進行分配記憶體大小的。但是對於不同的編譯器,結果是不同的,在VC++6.0中是怎麼個分配情況呢?用一下C中的關鍵字sizeof()來測試下,注意sizeof()不是函式哦!只是關鍵字而已。下圖就是在VC++6.0中的位元組分配情況:


下面來分析一下,C中結構體中成員變數的寫法,對佔用記憶體的影響。


卻發現結果不是13個位元組?卻是24個位元組?為什麼呢?哦!肯定是編譯起的問題,對,沒錯,就是編譯器的問題,VC++6.0預設是按照成員變數本身型別來對齊的,比如char 佔一個位元組,就會按照1個位元組對齊,short佔兩個位元組,就會按照2個位元組對齊,同理,int 4個位元組對齊,

預設方式下對齊步驟為:

1.成員變數都按照自己的對齊方式對齊

2.最後整個結構體在按照最大對齊引數對齊 也就是圓整法。

比如上面例子中:第一個成員為int型,所以按照4個位元組對齊(第一個成員的偏移值都是0)位元組對齊,說白了就是當前的偏移地址必須為n的整數倍,比如4個位元組對齊,就是說當前的偏移位元組數必須為4的倍數,因為第一個成員都是從offset為0開始的,所以先上4個位元組來存Int,然後第二個為double,佔8個位元組,也就是此時偏移地址,必須為8的倍數,明顯前面只有4個位元組,不能被8整除,所以必須在填4個位元組的空白位元組,然後在填充8個位元組給ch,最後一個為char型別的,佔一個位元組,都能被1整除。所以成員變數對齊後,佔17個位元組。最後為整體對齊,也就是sizeof(stu)的大小了,按照整體的規則,必須為最大對齊引數的整數倍,max(sizeof(int,double,char)=8所以17往上加,第一個被8整除的就是24,所以最後sizeof後為24。

好我們在結構體中把各個結構體成員變數順序變一下,看下佔用多少記憶體



同理按照上面分析可得到上圖所示。

那麼程式設計師如何按照自己的方式來記憶體對齊呢?用預編譯命名

#pragma pack(n)

.......

#pragma pack  中間的程式碼都將按照n位元組來對齊。

具體規則如下:本質和上面兩條規則一樣

1.各個成員變數按照min(n,sizeof(item))來對齊

比如 int i;這個時候,int佔4個位元組,n=1,此時就是按照1個位元組來對齊的。

2.整體對齊的時候,還是按照最大的對齊引數來對齊。

這裡最大的對齊引數為每個成員變數所最大的對齊引數.y=min(maxsizeof(item),n)
可以看出當n=1時,將按照成員變數本身對齊。


相關文章