sizeof對於大多數人來說是即熟悉由陌生的。熟悉是指大家基本都用過,也知道sizeof是操作符不是函式;陌生就是指sizeof在計算自定義型別的時候,會涉及記憶體對齊方式,返回結果往往與我們想的大相徑庭。本文就是結合記憶體對齊方式來介紹如何求sizeof的返回值。先來做個測試,各位看官如能準確說出下面幾個結構體的sizeof大小的話,樓主覺得你已經沒有必要再看下去,請出門左拐~
struct st1
;struct st2
;
#pragma pack(push)
#pragma pack(4)
struct st3
; #pragma pack(pop)
#pragma pack(8)
struct inst;
struct s2 ;
#pragma pack()
以上四個結構體sizeof的返回值,在vs上執行的結果和在linux執行的結果會有所差異,個人覺得是g++做了優化。以下的討論全是基於在vs上執行的結果,結果與linux有差異的地方會特別指出。下面開始進入正題。
理論來說變數的記憶體位址可以是任意位置,但為了提高cpu的效率,減少讀週期,編譯器會對變數的位址進行對齊,預設情況下,vs的對齊方式要求滿足以下兩點:
1.各成員變數的起始位址相對於結構體起始位址的偏移量必須是該變數型別所佔位元組大小的倍數。各成員變數根據在結構體出現的次序申請空間,按照以上所說方式對齊調整位置,空位元組由vs自動補齊。
2.確保結構體大小為結構體位元組邊界數的倍數,結構體位元組邊界數是指結構體中占用空間最大的型別的位元組個數。
下面給出常見型別的大小和偏量:
型別 對齊方式(變數存放的起始位址相對於結構的起始位址的偏移量)
char 偏移量必須為sizeof(char)即1的倍數
int 偏移量必須為sizeof(int)即4的倍數
float 偏移量必須為sizeof(float)即4的倍數
double 偏移量必須為sizeof(double)即8的倍數
short 偏移量必須為sizeof(short)即2的倍數
講到這,我們可以正確的求出前兩個結構體的大小了,首先是st1,假設結構體起始位址為0,a佔8位元組,0是8的倍數,所以a放在位址0處,佔8個位元組。那麼下乙個位址為9,9是1的倍數(char b),所以b放在位址9處,佔位元組為1。因為c是4個位元組,所以偏移量要為4的倍數,9開始最近的4的倍數為12,所以中間補齊3個位元組,而c本身佔4個位元組。所以st1的大小為8+1+3(補)+4=16。16正好是st1位元組邊界數的倍數,所以最後不用再補齊,即st1的大小為16。
各位看官自行分析st2吧,st2的sizeof大小在vs下的執行結果是24,之所以不是20,因為要滿足要求2。此外,st2在linux下執行的結果是16,為什麼是16,個人覺得跟編譯器預設的 #pragma pack(n) 有關。g++應該是預設4位元組對齊。下面我就開始講一下在 #pragma pack(n)限制下的sizeof如何求。
1.如果n大於等於變數型別所占用的位元組數,則採用預設對齊方式。
2.如果n小於變數型別所占用的位元組數,則偏移量滿足是n的倍數即可,無需是變數型別所佔位元組的倍數。
3.結構體總大小的約束條件:如果n大於等於成員變數中最大的變數型別所佔位元組數,採用預設方式(即使邊界位元組數的倍數),否則為n的倍數即可。
現在我們來分析一下st3,首先是4位元組對齊,繼續假設結構體的起始位址為0,b因為(1<4)採用預設對齊方式,0是1的倍數,所以b的起始位址是0,接下來看a(8>4),此時不再是預設對齊方式,而是4位元組對齊方式,所以a的起始位址是4,不是之前的8。此時偏移量是12,是4的倍數,所以c剛好可以。到此結構的大小是1+3(補)+8 + 4=16;
結構總大小滿足是4的倍數(注意不是8)。所以最終結果是16。st3的執行結果在vs和linux下一致。
1.每個成員分別按自己的方式對齊,並能最小化長度。
2.複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在成員是複雜型別時,可以最小化長度。
3.對齊後的長度必須是成員中最大的對齊引數的整數倍,這樣在處理陣列時可以保證每一項都邊界對齊。
關於python物件必須要知道的事
標籤的傳遞不改變物件的記憶體位址,物件可大致分為內建物件,組織物件和結構物件 python內建物件 最小個體 他們是構成其他物件的基礎,這也是計算機存在的基礎。a 256b a print id a print id b 第一次結果 用reset釋放變數後 這是第二次結果 組織物件 關於個體的關係 ...
外鏈代發你必須要知道的事
過去,所有的站長都認同 seo的乙個 真理 內容為王,外鏈為皇。但隨著最近幾年對內容的注重,對外鏈的打壓,外鏈的作用越來越小。而最先飽受其衝的除了各站長外,就是各外鏈代發產業了,相信為了扳回不利局面,這些代發大神也拼了命的想法子,最具有代表性的就是這句話了 外鏈的作用越來越小,說明外鏈的質量越來越重...
關於鎖相環(PLL)必須要知道的事
一 鎖相環組成 鎖相環一般由三部分組成壓控振盪器 濾波器和鑑相器。最終使得輸入和輸出兩個頻率同步,且具有穩定的相位差。二 鎖相環作用 用來把輸入的時鐘頻率進行倍頻。三 鎖相環各個部分介紹 壓控振盪器 電壓變化控制輸出的振盪器,輸入電壓越高,輸出頻率越大!鑑相器 鑑定兩個輸入波形的相位,輸出占空比穩定...