日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

结构体内存对齐

發(fā)布時間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结构体内存对齐 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

結(jié)構(gòu)體內(nèi)存對齊

先看兩段代碼,兩段代碼僅順序不同,其結(jié)果輸出就出現(xiàn)了不同。

struct S {char c1;//1 8 1int i;//4 8 4char c2;//1 8 1 };struct S2 {char c1;char c2;int i; };int main() {struct S s = { 0 };struct S2 s2 = { 0 };printf("%d\n", sizeof(s));//12printf("%d\n", sizeof(s2));//8return 0; }

接下來對其中的S進行單獨分析:

struct S {char c1;//1int i;//4char c2;//1 };int main() {struct S s = { 0 };printf("%p\n", &s);//002FFED8printf("%p\n", &(s.c1));//002FFED8printf("%p\n", &(s.i));//002FFEDCprintf("%p\n", &(s.c2));//002FFEE0return 0; }

結(jié)構(gòu)體內(nèi)存對齊的規(guī)則:
1.結(jié)構(gòu)體的第一個成員永遠(yuǎn)都對齊到結(jié)構(gòu)體的起始位置處。

2.從第二個成員開始,每個成員都對齊到某個對齊數(shù)的整數(shù)倍處。

對齊數(shù):成員自身大小和默認(rèn)對齊數(shù)的較小值
默認(rèn)對齊數(shù):VS-8 Linux-gcc-4

3.結(jié)構(gòu)體的總大小是所有成員中最大對齊數(shù)的整數(shù)倍。

是一種以空間換時間的做法。

4.嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。

struct S3 {double d;//0-7char c;//8//9-11空余int i;//12-15 };struct S4 {char c1;struct S3 s3;double d; };int main() {printf("%d\n", sizeof(struct S3));//16printf("%d\n", sizeof(struct S4));//32return 0; }


為什么存在內(nèi)存對齊:

  • 平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。
  • 性能原因: 數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對齊。 原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問僅需要一次訪問。
  • offsetof—計算偏移量

    1.頭文件:#include<stddef.h>
    2.

    int main() {printf("%d\n", offsetof(struct S, c1));//0printf("%d\n", offsetof(struct S, i));//4printf("%d\n", offsetof(struct S, c2));//8return 0; }

    3.宏參數(shù)無類型
    \為續(xù)行符(將一行拆成兩行) 也可以看成轉(zhuǎn)義字符
    后面加什么就轉(zhuǎn)義什么
    直接敲回車–轉(zhuǎn)義回車

    #define my_offsetof(structName,memName) \ (int)&(((structName*)0)->memName) int main() {printf("%d\n", my_offsetof(struct S, c1));//0printf("%d\n", my_offsetof(struct S, i));//4printf("%d\n", my_offsetof(struct S, c2));//8return 0; }

    僅僅通過更換成員順序,就可以改變所占字節(jié)大小,那在設(shè)計結(jié)構(gòu)體的時候,我們既要滿足對齊,又要節(jié)省空間,應(yīng)該:
    1.讓占用空間小的成員盡量集中在一起。
    2.修改默認(rèn)對齊數(shù)

    #include <stdio.h> #pragma pack(8)//設(shè)置默認(rèn)對齊數(shù)為8 struct S1 {char c1;int i;char c2; }; #pragma pack()//取消設(shè)置的默認(rèn)對齊數(shù),還原為默認(rèn)#pragma pack(1)//設(shè)置默認(rèn)對齊數(shù)為1 struct S2 {char c1;int i;char c2; }; #pragma pack()//取消設(shè)置的默認(rèn)對齊數(shù),還原為默認(rèn) int main() {//輸出的結(jié)果是什么?printf("%d\n", sizeof(struct S1));//12printf("%d\n", sizeof(struct S2));//6return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的结构体内存对齐的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。