亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

深入內存對齊的詳解

2020-01-26 16:15:06
字體:
來源:轉載
供稿:網友

1.引子

    在結構中,編譯器為結構的每個成員按其自身的自然對界(alignment)條件分配空間。各個成員按照它們被聲明的順序在內存中順序存儲,第一個成員的地址和整個結構的地址相同。

    例如,下面的結構各成員空間分配情況(假設對齊方式大于2字節,即#pragma pack(n), n = 2,4,8...下文將討論#pragmapack()):

復制代碼 代碼如下:

struct test
{
     char x1;
     short x2;
     float x3;
     char x4;
};

    結構的第一個成員x1,其偏移地址為0,占據了第1個字節。第二個成員x2為short類型,其起始地址必須2字節對界,即偏移地址是2的倍數。因此,編譯器在x2和x1之間填充了一個空字節,將x2放在了偏移地址為2的位置。結構的第三個成員x3和第四個成員x4恰好落在其自然對界地址上,在它們前面不需要額外的填充字節。在test結構中,成員x3要求4字節對界,是該結構所有成員中要求的最大對界單元,因而test結構的自然對界條件為4字節,整個結構體的大小是最大對界單元大小的整數倍(結構體內部有結構體時也遵循這個規則,下文將提到),編譯器在成員x4后面填充了3個空字節。整個結構所占據空間為12字節。
    關于為什么要內存對齊,參考<解析內存對齊 Data alignment: Straighten up and fly right的詳解>。看了這篇文章便可以更輕松的理解下面的內容。

    好了,下面說說#pragma pack:

2.#pragma pack()

    該預處理指令用來改變對齊參數。在缺省情況下,C編譯器為每一個變量或數據單元按其自然對界條件分配空間。一般地,可以通過下面的方法來改變缺省的對齊參數:

     ? 使用偽指令#pragma pack (n),C編譯器將按照n字節對齊。

     ? 使用偽指令#pragma pack (),取消自定義字節對齊方式。

也可以寫成:

#pragma pack(push,n)

#pragma pack(pop)

#pragma pack (n)表示每個成員的對齊單元不大于n(n為2的整數次冪)。這里規定的是上界,只影響對齊單元大于n的成員,對于對齊字節不大于n的成員沒有影響。其實從字面意思,pack是“包裹,打包”的意思,#pragma pack(n)規定n個字節是一個“包裹”,個人認為實在不理解的話可以認為處理器一次性可以從內存中讀/寫n個字節,這樣好理解。對于大小小于n的成員,當然是按照自己的對齊條件對齊,因為不論怎么放都可以一次性取出。對于對齊條件大于n個字節的成員,成員按照自身的對齊條件對齊和按照n字節對齊需要相同的讀取次數,但按照n字節對齊節省空間,何樂而不為呢??梢詤⒖嘉疑厦嫣岬降?lt;解析內存對齊 Data alignment: Straighten up and fly right的詳解>。下面是一位大牛的觀點,和我說的是一個意思:

   All it means is that each member of it will require alignment no greater than n.It doesn't mean that each member will have alignment requirement n.Notice, after all, it's called pack and not align for a reason-- precisely because it controls packing, not alignment.

另外,GNU C還有如下的一種方式:

     ? __attribute__((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大于n,則按照最大成員的長度來對齊。

     ? __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,按照實際占用字節數進行對齊。

以上的n = 1, 2, 4, 8, 16... 第一種方式較為常見。

3.結構體內成員如何找出自己的位置

首先遵循以下規則:

1.  每個成員分別取自己的對齊方式和#pragma pack指定的對齊參數二者的較小值作為自己的對齊方式。

2.  復雜類型(如結構)的對齊方式是該類型聲明時所使用的對齊方式,或者說是聲明時它的所有成員使用的對齊參數的最大值,最后和此時的#pragma pack指定的對齊參數二者取極小值。大牛是這么說的:

The documentation for #pragma pack(n) says that "The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member,whichever is smaller". However I think this is incorrect; the docs should say that the alignment of a member will be on a boundary that is either a multiple of n or the alignment requirement of the member, whichever is smaller.

3.  對齊后的長度必須是成員中最大的對齊參數(不是成員的大小)的整數倍,這樣在處理數組時可以保證每一項都邊界對齊。

4.  對于數組,比如:char a[3];這種,它的對齊方式和分別寫3個char是一樣的。也就是說它還是按1個字節對齊.

        如果寫: typedef char Array3[3];

        Array3這種類型的對齊方式還是按1個字節對齊,而不是按它的長度。

5.  不論類型是什么,對齊的邊界一定是1,2,4,8,16,32,64....中的一個。

看一個簡單的例子:

復制代碼 代碼如下:

#pragma pack(8)
struct s1
{
    short a;
    long b;
};
struct s2
{
    char c;
    s1 d;
    long long e;
};
#pragma pack()

    成員對齊有一個重要的條件:每個成員分別對齊。即每個成員按自己的方式對齊.

    也就是說上面雖然指定了按8字節對齊,但并不是所有的成員都是以8字節對齊。其對齊的規則是,每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(這里是8字節)中較小的一個對齊。并且結構的長度必須為所用過的所有對齊參數的整數倍(只要是最大的對齊參數的整數倍即可),不夠就補空字節(視編譯器而定)。

    S1中,成員a是2字節默認按2字節對齊,指定對齊參數為8,這兩個值中取2,a按2字節對齊;成員b是4個字節,默認是按4字節對齊,這時就按4字節對齊,a后補2個字節后存放b,所以sizeof(S1)應該為8。8是4的倍數,滿足上述的第3條規則。

    S2中,c和S1中的a一樣,按2字節對齊,而d是個結構,它是8個字節,它按什么對齊呢?對于結構來說,它的默認對齊方式就是該結構定義(聲明)時它的所有成員使用的對齊參數中最大的一個,S1的是4,小于指定的8。所以成員d就是按4字節對齊,c后補2個字節,后面是8個字節的結構體d。成員e是8個字節,它是默認按8字節對齊,和指定的一樣,所以它對到8字節的邊界上,這時,已經使用了12個字節了,所以d后又補上4個字節,從第16個字節開始放置成員e。這時,長度為24,已經可以被最大對齊參數8(成員e按8字節對齊)整除。這樣,一共使用了24個字節。

   上面的不夠復雜?再來一個:

復制代碼 代碼如下:

#pragma pack(4)
struct s1
{
    char a;
    double b;
};
#pragma pack()

#pragma pack(2)
struct s2
{
    char c;
    struct s1 st1;
};
#pragma pack()

 
#pragma pack(2)
struct s3
{
    char a;
    long b;
};
#pragma pack()

#pragma pack(4)
struct s4
{
    char c;
    struct s3 st3;
};
#pragma pack()

    先看s1,a放在偏移地址為0的位置(第一個字節)。b默認8字節對齊,但指定對齊參數是4字節,所以b按4字節對齊,放在偏移地址為4的位置,a后補3個字節。所以sizeof(s1)是12。結構體s1的對齊參數是4,下面會用到。

    再看s2,c放在第一個字節。st1自己的對齊參數是4,但此時指定的對齊參數是2,所以st1按照2字節對齊,c后補一個字節后存放st1。注意,st1內部是不會變的,聲明s1時是什么樣就是什么樣,因為我們要保證sizeof(s2.st1) == sizeof(s1),如果不這樣就亂套了。這樣sizeof(s2)是14。結構體s2的對齊參數是2,14是2的整數倍。

    再看s3,a放在第一個字節。b默認4字節對齊,但指定的對齊參數是2,所以b按2字節對齊,放在偏移地址為2的位置,a后補一個字節。sizeof(s3)是6。結構體s3的對齊參數是2(后面會用到),6是2的整數倍。

    最后看s4,c放在第一個字節。st3自己的對齊參數是2,指定的對齊參數是4,所以st3取極小值,按2字節對齊,放在偏移地址為2的位置,c后補一個字節。sizeof(s4)是8,結構體的對齊參數是2,8是2的整數倍。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美高清在线播放| 国产成人综合一区二区三区| 精品色蜜蜜精品视频在线观看| 亚洲欧洲日本专区| 欧美激情奇米色| 欧美日韩午夜视频在线观看| 日韩免费高清在线观看| 国产欧美日韩丝袜精品一区| 亚洲自拍欧美色图| 国产成人精品一区二区三区| 在线日韩欧美视频| 日韩欧美国产激情| 日本一本a高清免费不卡| xxx成人少妇69| 18久久久久久| 亚洲福利视频免费观看| 国产精品6699| 一区二区欧美在线| 亚洲男女自偷自拍图片另类| 亚州欧美日韩中文视频| 精品久久久av| 久久香蕉国产线看观看网| 久久精品视频一| 在线观看欧美www| 最近2019中文字幕mv免费看| 欧美一区二区三区四区在线| 久久夜色精品国产亚洲aⅴ| 久久久精品一区二区| 日韩免费看的电影电视剧大全| 91精品视频在线免费观看| 亚洲自拍偷拍一区| 欧美激情日韩图片| 日韩天堂在线视频| 欧美日韩高清在线观看| 国产suv精品一区二区| 亚洲淫片在线视频| 亚洲国产天堂久久国产91| 日韩中文综合网| 国产成人亚洲综合91精品| 中文字幕日韩在线播放| 欧美日韩国产限制| 国产在线观看精品| 这里只有视频精品| 亚洲欧洲第一视频| 日韩一区二区在线视频| 国产日产欧美精品| 日韩动漫免费观看电视剧高清| 精品一区二区三区四区| 国产视频精品va久久久久久| 国产狼人综合免费视频| 欧美理论电影在线播放| 在线观看亚洲视频| 韩国福利视频一区| 97人人爽人人喊人人模波多| 国产成人综合精品在线| 伊人伊成久久人综合网小说| 日韩在线视频中文字幕| 成人午夜在线观看| 精品国内亚洲在观看18黄| 不用播放器成人网| 欧美激情第99页| 亚洲午夜未满十八勿入免费观看全集| 亚洲精品免费av| 日本三级韩国三级久久| 欧美另类高清videos| 国产自产女人91一区在线观看| 北条麻妃一区二区在线观看| 国产精品久久久久久影视| 国产精品一区二区三区成人| 亚洲欧美三级在线| 亚洲男人的天堂在线播放| 国语自产精品视频在线看抢先版图片| 欧美另类暴力丝袜| 成人xxxx视频| 国产亚洲aⅴaaaaaa毛片| 欧美最猛性xxxxx亚洲精品| 亚洲国产另类久久精品| 亚洲精品中文字| 97色在线播放视频| 91精品久久久久| 国产精品国语对白| 久久久噜噜噜久噜久久| 97香蕉久久超级碰碰高清版| 国产精品va在线播放我和闺蜜| 日韩成人在线视频观看| 欧美精品xxx| 97在线观看视频| 欧美国产乱视频| 亚洲人成五月天| 亚洲人成在线电影| 92看片淫黄大片欧美看国产片| 中文字幕无线精品亚洲乱码一区| 国产精品视频地址| 国产精品扒开腿做爽爽爽的视频| 亚洲国产成人91精品| 久久99国产综合精品女同| 精品国产乱码久久久久久天美| 亚洲丁香婷深爱综合| 久久精品国产欧美亚洲人人爽| 国产精品成人一区二区三区吃奶| 亚洲香蕉伊综合在人在线视看| 国产日韩欧美夫妻视频在线观看| 久久综合九色九九| 久久久久久久久网站| 中文综合在线观看| 国产极品jizzhd欧美| 久色乳综合思思在线视频| 国产一区二区三区在线播放免费观看| 国产亚洲欧美日韩精品| 亚洲精品久久久久中文字幕欢迎你| 国产视频久久久| 欧美国产日本在线| 欧美日韩国产中文精品字幕自在自线| 日韩成人免费视频| 亚洲一区二区久久| 精品久久久91| 久热精品视频在线观看| 日韩在线国产精品| 欧美国产日本在线| 青草青草久热精品视频在线网站| 日本久久久久亚洲中字幕| 国产不卡一区二区在线播放| 亚洲精品少妇网址| 日韩国产精品一区| 亚洲日本成人女熟在线观看| 丝袜情趣国产精品| 在线观看91久久久久久| 国产日韩在线免费| 国产精品揄拍一区二区| 成人精品一区二区三区| 午夜精品99久久免费| 中文字幕精品www乱入免费视频| www欧美日韩| 国产suv精品一区二区三区88区| 91免费福利视频| 欧美性猛交丰臀xxxxx网站| 日韩中文字幕在线视频播放| 精品视频久久久| 日韩在线观看免费av| 欧美在线激情视频| 午夜精品一区二区三区在线播放| 亚洲国产精品999| 欧美做爰性生交视频| 久久精品视频亚洲| 91在线观看欧美日韩| 久久视频在线免费观看| 精品国偷自产在线| 伊人久久大香线蕉av一区二区| 欧美精品电影在线| 国产精品高潮呻吟久久av黑人| 2019中文在线观看| 亚洲精选一区二区| 国产精品久久久久久久久久久久久久| 亚洲免费高清视频| 久久99久久99精品免观看粉嫩| 亚洲国产精品电影在线观看| 亚洲人线精品午夜| 伊人青青综合网站| 亚洲精品综合精品自拍| 欧美日本中文字幕| 欧美电影免费观看大全| 亚洲高清一二三区| 欧美亚洲视频一区二区| 成人黄色av免费在线观看|