這階段一直想寫一篇部落格,其實有好多東西,先寫一下c語言中的記憶體對齊吧。
大家都知道,在c語言中定義乙個變數,char是占用乙個位元組的,int占用四個位元組,float占用四個位元組,double占用八個位元組,short占用兩個位元組,long int占用四個位元組,long long神馬的是64位機器用的,暫時不討論。
上面說基本的資料型別所占用的位元組數,程式的測試咱們printf一下(由於是菜鳥,所以咱們就不玩f8,f9的問題了)。程式如下:
#includeint main(void)
好了,我們可以知道這些資料型別占用的位元組空間了,那麼現在提出乙個問題。
struct student
stu;
當我們以4位元組的方式編譯的時候,請問printf("%d",sizeof(stu));
我一直都認為這個列印的值是6,因為很明顯嘛,short是兩個位元組的,long是四個位元組的,所以列印出來的大小就是6個位元組嘛。那好,請在vc下編譯測試一下吧。
結果出來的是8!!!
出乎意料了,這就是記憶體對齊。
記憶體對齊的意義在於:處理器是以規定的位元組數進行讀取位元組數的,我們編譯的是以4位元組讀取位元組數,這就是問題的所在。而且,讀取的塊的大小必須是2的n次冪。
下面我們解釋一下,上面那個結構體列印出來的大小是8的原因。
原因:short型別占用兩個位元組,四個位元組是一塊的情況下,那麼當乙個short型別占用兩個位元組以後還剩下兩個位元組,但是接下來我們要儲存的是四個位元組的long型,如果按照列印六的話,那麼我們的處理的取值將會矇圈,所以實際上編譯器把這兩個資料分配的空間是short占用兩個位元組後空出兩個位元組的位置,這樣完成了乙個四個位元組的塊,然後接下來的乙個long型占用四個位元組,這樣完成了兩個塊,所以我們列印出來的是8 。空說估計一會自己都暈了,所以畫個圖:
同時還要說一下記憶體的對齊的規則:
①必須要按照編譯器指定的位元組數進行讀取,同時還要考慮怎麼樣才可以使編譯器讀取資料最快捷。
②另外最後占用的位元組數必須是整個結構體中位元組數最大資料型別的整數倍。
還有一些其他規則,下面再進行介紹。
乙個結構體的問題差不多了吧?那麼再看乙個:
#include struct student
stu1;
struct teacher
stu2;
int main()
咱們還是列印,那麼列印出來的是多少呢?
這裡說個插曲,在vc中預設的是8位編譯,這個時候列印出來的是8和24,在linux下的gcc編譯,列印出來的是8和20 。一直認為vc是4位編譯,所以走了一些彎路,後來使用巨集條件判斷才知道vc是4位編譯。下面分別說一下這種結構體巢狀結構體的記憶體對齊。
上面說的是4位的,那麼這裡我們還說繼續先說4位的。
列印20的原因:
先說一下第二個結構體的第乙個成員char,占用的是乙個位元組。第乙個結構體的第乙個成員short占用兩個位元組,第二個成員占用四個位元組。好了,暫停一下,我這個時候我就疑惑了,為什麼char和short不在乙個四位元組的塊中呢,這樣編譯器也可以按照四位元組進行很快速的讀取啊?但是這個時候應該考慮的是,第乙個結構體已經被編譯器分配好了乙個完整的空間,所以這個short是不可以並到第乙個結構體中的。回到主題,第乙個char單獨占用乙個位元組的四位元組的塊,第乙個結構體占用連個四位元組的塊,double為8位元組,占用兩個四位元組的塊,最後占用的是五個四位元組的塊。所以列印20 。
上圖:
下面說一下當按照8位元組進行編譯的時候列印出24的原因。(雖然是8位元組進行編譯的,但是讀取的還是按照四個位元組進行讀取的,這樣的話前面說的原則仍然成立。)
原因如下:第乙個char占用了乙個位元組,但是按照8位元組儲存,按照4位元組讀取,所以char占用了8位元組前面的4位元組,後面的四個位元組被short占用,這樣也完成了處理器最快速度讀取並且沒有破壞第乙個結構體的整體性。剩下的乙個乙個long占用了乙個四位元組,我的同學說這個八字節的塊要空出來四個,因為不可以把後來的double拆開,但是我認為這麼解釋不是很合理,我也不清楚原因是什麼,所以暫時擱置。
上圖:
先說這麼多吧,這裡面還有一些小東西,太晚了,各位建軍節快樂吧,我明天還要繼續我苦逼的實訓道路。
C語言中記憶體對齊問題
在日常的開發工作中,時常要用到結構體的定義工作,但是結構體中資料的定義順序是否合理直接影響了結構體所佔記憶體的大小,所以了解c語言中記憶體對齊的知識十分有必要。關於記憶體對齊的原則,我們首先討論沒有定義巨集 pragam pack 的情況,在該巨集沒有定義的情況之下,c語言中結構體的記憶體對齊問題主...
C語言中記憶體對齊詳解
首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include iostream 45 using namespace std 67 struct st1 8 1314 struct st215 20 21int main 2227 程式的輸出結果為 sizeof st...
C語言中記憶體對齊小結
一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。2.對齊的作...