字節對齊詳解

    以前一直以爲字節對齊是個癥結,平時的實際應用中接觸的太多了,若是不去弄懂它,感受它就是一個短板,因而着手開始研究了它,今天在公司的例行講解中又講到了這個,回來想一想仍是整理下,算是給一個總結概括。
    首先我不得不提一個預編譯命令 #pragma pack(),爲了更好的切入主題我暫且只關心#pragma pack(n)這種設置當前字節對齊值爲n的用法,有一點必須注意,n只有等於1,2,4,8,16纔是有效值,其它的設置都是無效的。
    下面,我從結構體入手,先看一段代碼佈局

#include <stdio.h>

#pragma pack (1)
struct stu1
{
	int b;
};
#pragma pack ()

struct stu2
{
	char a;
	struct stu1 b;

};

int main()
{
	printf("sizeof(struct stu1)=%d\nsizeof(struct stu2)=%d\n", sizeof(struct stu1),sizeof(struct stu2));
	return 1;
}

     運行結果
    
    對於結構體stu1來講,它的字節對齊是1,是否是以爲很奇怪,一般咱們查資料的時候都會說結構體的字節對齊值取的是結構體中全部類型中字節對齊值最大的那個,那若是這樣的話,stu1難道不該該是4嗎?變量a的後面不用補零嗎?    
    問題進行到這裏,咱們有必要弄懂兩個概念: 有效字節對齊值 類型自身字節對其值
    int 型在32位系統上所佔字節數爲4,字節對齊值爲4,即int型自身字節對齊值爲4;相似的還有char、double等等;
    struct結構體的自身字節對齊值爲結構體中全部類型裏自身字節對齊值最大的那個;
    有效字節對齊值,實際上是在最終實際內存操做中字節對齊的值,取的值是系統指定值(或默認值)與類型自身字節對齊值 較小 的那個。如上例經過#pragma pack (1)指定字節對齊值爲1,而結構體自身的字節對齊值爲4(取int的),因而stu1的有效字節對齊值爲1,因此在結構體stu2中,stu1相對於stu2結構體的首地址偏移量(變量a所佔的內存大小)除以stu1的有效字節對齊值是整數,符合條件,故而不用在變量a以後補0,結果爲5.
    弄清楚了這些概念,那麼咱們再回顧一下結構體內存分配的原則:

    1. 結構體內部,每一個變量至關於結構體首地址的偏移量的大小必須是這個變量類型有效字節對齊值的整數倍。    
    2. 結構體自身,結構體分配內存的大小必須是結構體有效字節對齊值的整數倍。
    好了,弄清楚了這些概念,咱們再開始看一段程序,來驗證一下這些結論
    
spa

#include <stdio.h>

#pragma pack (2)
struct stu1
{
	char a;
	int b;
};
#pragma pack ()

struct stu2
{
	char a;
	int b;

};

int main()
{
	printf("sizeof(struct stu1)=%d\nsizeof(struct stu2)=%d\n", 
			sizeof(struct stu1),sizeof(struct stu2));
	return 1;
}


    運行結果

    

    分析
       變量                   a        b
       stu1內存佈局      *0      ****
code

       stu2內存佈局      *000   ****     (*表示a、b的實際值,0表示爲了字節對齊補的0值內存

相關文章
相關標籤/搜索