C/C++語言中結構體字節對齊方法詳解

爲什麼要字節對齊:

         爲了更快的讀取數據;不是本文重點,不想多解釋;

對齊規則:

1、確定對齊單位

    1、環境默認對齊單位

       WIN默認8字節對齊

       Linux 32位 默認4字節對齊,64位默認8字節對齊

    2、結構體最大數據類型長度

        1、含有數組:數組就是多個基本類型變量,比如  char a[10],就是有a[0] 到  a[9]  共10個char類型變量;

        2、含有結構體:比較嵌套的結構體中最大與本結構體中最大,取大的那個;

    3、預編譯指令#pragma pack(n)手動設置     n取1 2 4 8 16

    上面三者取最小的,就是實際對齊單位;

2、結構體(struct)的數據成員,第一個數據成員放的位置offset在0的地方,以後每個數據成員的offset爲該數據成員大小的整數倍的地方(比如int在32位機爲4字節,則要從4的整數倍地址開始存儲)

3、結構體作爲成員的對齊規則。

      如果一個結構體B裏嵌套另一個結構體A,則結構體A應從offset爲A內部最大成員的整數倍的地方開始存儲。(struct B裏存有struct A,A裏有char,int,double等成員,那A應該從8的整數倍開始存儲。),結構體A中的成員的對齊規則仍滿足2、3。

注意:

        1. 結構體A所佔的大小爲該結構體成員內部最大元素的整數倍,不足補齊。

        2. 不是直接將結構體A的成員直接移動到結構體B中

4、結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。

 

練習

1、按照規則1;結構體b的對齊單位是多少?

#pragma pack(8)
struct A
{
	int a;
	double b;
	float c;
};

struct
{
	char e[10];
	int f;
	short h;
	struct A i;
}B;

  結果爲8;

2、驗證規則3中結構體A應從offset爲A內部最大成員的整數倍的地方開始存儲;計算結構體b的大小

#pragma pack(8)
struct A
{
	short a;
	int b;
};

struct
{
	char e[2];
	int f;
	short g;
	struct A j;
	double i;

}B;

main() {
	printf("short%d\n", sizeof(short));//2
	printf("int%d\n", sizeof(int));//4
	printf("double%d\n", sizeof(double));//8
	printf("B%d",sizeof( B));//32
}

結果爲32而不是24說明其存放方式是

e e * * f f f f
g g * * a a * *
b b b b * * * *
i i i i i i i i

 

而不是

e e * * f f f f
g g a a b b b b
i i i i i i i i

 

2、驗證規則3中1. 結構體A所佔的大小爲該結構體成員內部最大元素的整數倍,不足補齊。;計算結構體b的大小

#pragma pack(8)
struct A
{
	short a;
	int b;
	short c;
};

struct
{
	char e[2];
	int f;
	short g;
	struct A j;
	short k;
	double i;

}B;

main() {

	printf("B%d",sizeof( B));//40
}

結果是40而不是32;說明存放是

e e * * f f f f
g g * * a a * *
b b b b c c * *
k k * * * * * *
i i i i i i i

i

 

而不是

e e * * f f f f
g g * * a a * *
b b b b c c k k
i i i i i i i i
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章