生活随笔
收集整理的這篇文章主要介紹了
结构体内存对齐
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
結構體內存對齊
先看兩段代碼,兩段代碼僅順序不同,其結果輸出就出現了不同。
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;
}
結構體內存對齊的規則:
1.結構體的第一個成員永遠都對齊到結構體的起始位置處。
2.從第二個成員開始,每個成員都對齊到某個對齊數的整數倍處。
對齊數:成員自身大小和默認對齊數的較小值
默認對齊數:VS-8 Linux-gcc-4
3.結構體的總大小是所有成員中最大對齊數的整數倍。
是一種以空間換時間的做法。
4.嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。
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;
}
為什么存在內存對齊:
平臺原因(移植原因): 不是所有的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能在某些地址處取某些特定類型的數據,否則拋出硬件異常。性能原因: 數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。 原因在于,為了訪問未對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。
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.宏參數無類型
\為續行符(將一行拆成兩行) 也可以看成轉義字符
后面加什么就轉義什么
直接敲回車–轉義回車
#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;
}
僅僅通過更換成員順序,就可以改變所占字節大小,那在設計結構體的時候,我們既要滿足對齊,又要節省空間,應該:
1.讓占用空間小的成員盡量集中在一起。
2.修改默認對齊數
#include <stdio.h>
#pragma pack(8)//設置默認對齊數為8
struct S1
{char c1;int i;char c2;
};
#pragma pack()//取消設置的默認對齊數,還原為默認#pragma pack(1)//設置默認對齊數為1
struct S2
{char c1;int i;char c2;
};
#pragma pack()//取消設置的默認對齊數,還原為默認
int main()
{//輸出的結果是什么?printf("%d\n", sizeof(struct S1));//12printf("%d\n", sizeof(struct S2));//6return 0;
}
總結
以上是生活随笔為你收集整理的结构体内存对齐的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。