32位cpu是以雙字(dword)為單位進行資料傳輸的,因此我們的資料無論是8位或16位都是以雙字進行資料傳輸。
比如,乙個int型別4位元組的資料如果放在上圖記憶體位址1開始的位置,那麼這個資料占用的記憶體位址為1~4,那麼這個資料就被分為了2個部分,乙個部分在位址0~3中,另外一部分在位址4~7中,又由於32位cpu以雙字進行傳輸,所以,cpu會分2次進行讀取,一次先讀取位址0~3中內容,再一次讀取位址4~7中資料,最後cpu提取並組合出正確的int型別資料,捨棄掉無關資料。那麼反過來,如果我們把這個int型別4位元組的資料放在上圖從位址0開始的位置會怎樣呢?讀到這裡,也許你明白了,cpu只要進行一次讀取就可以得到這個int型別資料了。沒錯,就是這樣,這次cpu只用了乙個週期就得到了資料,由此可見,對記憶體資料的擺放是多麼重要啊,擺放正確位置可以減少cpu的使用資源。
那麼,記憶體對齊有哪些原則呢?我總結了一下大致分為三條:
第一條:第乙個成員的首位址為0
第二條:每個成員的首位址是自身大小的整數倍
第二條補充:以4位元組對齊為例,如果自身大小大於4位元組,都以4位元組整數倍為基準對齊。
第三條:最後以結構總體對齊。
第三條補充:以4位元組對齊為例,取結構體中最大成員型別倍數,如果超過4位元組,都以4位元組整數倍為基準對齊。(其中這一條還有個名字叫:「補齊」,補齊的目的就是多個結構變數挨著擺放的時候也滿足對齊的要求。)
上述的三原則聽起來還是比較抽象,那麼接下來我們通過乙個例子來加深對記憶體對齊概念的理解,下面是乙個結構體,我們動手算出下面結構體一共占用多少記憶體?假設我們以32位平台並且以4位元組對齊方式:
#pragma pack(4)
typedef struct memalign
memalign;
下圖為對齊後結構如下:
我們就以這個圖來講解是如何對齊的:
第乙個成員(char a[18]):首先,假設我們把它放到記憶體開始位址為0的位置,由於第乙個成員佔18個位元組,所以第乙個成員占用記憶體位址範圍為0~18。
第二個成員(double b):由於double型別佔8位元組,又因為8位元組大於4位元組,所以就以4位元組對齊為基準。由於第乙個成員結束位址為18,那麼位址18並不是4的整數倍,我們需要再加2個位元組,也就是從位址20開始擺放第二個成員。
第三個成員(char c):由於char型別佔1位元組,任意位址是1位元組的整數倍,所以我們就直接將其擺放到緊接第二個成員之後即可。
第四個成員(int d):由於int型別佔4位元組,但是位址29並不是4的整數倍,所以我們需要再加3個位元組,也就是從位址32開始擺放這個成員。
第五個成員(short e):由於short型別佔2位元組,位址36正好是2的整數倍,這樣我們就可以直接擺放,無需填充位元組,緊跟其後即可。
這樣我們記憶體對齊就完成了。但是離成功還差那麼一步,那是什麼呢?對,是對整個結構體補齊,接下來我們就補齊整個結構體。那麼,先讓我們回顧一下補齊的原則:「以4位元組對齊為例,取結構體中最大成員型別倍數,如果超過4位元組,都以4位元組整數倍為基準對齊。」在這個結構體中最大型別為double型別(佔8位元組),又由於8位元組大於4字 節,所以我們還是以4位元組補齊為基準,整個結構體結束位址為38,而位址38並不是4的整數倍,所以我們還需要加額外2個位元組來填充結構體,如下圖紅色的就是補齊出來的空間:、
我們可以通過乙個程式來觀察記憶體變化:
#include #include // 通過預編譯來通知編譯器我們以4位元組對齊
#pragma pack(4)
// 用於測試的結構體
typedef struct memalign
memalign;
int main()
C語言記憶體對齊和結構補齊
首先我們先看看下面的c語言的結構體 cpp view plain copy typedef struct memalign memalign 以上這個結構體占用記憶體多少空間呢?也許你會說,這個簡單,計算每個型別的大小,將它們相加就行了,以32為平台為例,int型別佔4位元組,char占用1位元組,...
記憶體對齊和記憶體補齊
記憶體對齊 第乙個資料成員放在offset為0的地方,對齊按照對齊係數和自身所占用的位元組數中,兩者比較小的那個進行對齊。記憶體補齊在struct或者union資料成員完成各自對齊之後,struct或者union本身也要對齊,對齊按照對齊係數和struct或者union中最大資料成員長度中比較小的那...
記憶體對齊與補齊
首先我們先看看下面的c語言的結構體 相信學過彙編的朋友都很熟悉這張圖,這張圖就是cpu與記憶體如何進行資料交換的模型,其中,左邊藍色的方框是cpu,右邊綠色的方框是記憶體,記憶體上面的0 3是記憶體位址。這裡我們這張圖是以32位cpu作為代表,我們都知道,32位cpu是以雙字 dword 為單位進行...