關於C語言中的結構體對齊

來源:互聯網
上載者:User

(1)什麼是位元組對齊

一個變數佔用 n 個位元組,則該變數的起始地址必須能夠被 n 整除,即: 存放起始地址 % n = 0, 對於結構體而言,這個 n 取其成員種的資料類型占空間的值最大的那個。

(2)為什麼要位元組對齊

記憶體空間是按照位元組來劃分的,從理論上說對記憶體空間的訪問可以從任何地址開始,但是在實際上不同架構的CPU為了提高訪問記憶體的速度,就規定了對於某些類型的資料只能從特定的起始位置開始訪問。這樣就決定了各種資料類型只能按照相應的規則在記憶體空間中存放,而不能一個接一個的順序排列。

舉個例子,比如有些平台訪問記憶體位址都從偶數地址開始,對於一個int型(假設32位系統),如果從偶數地址開始的地方存放,這樣一個讀周期就可以讀出這個int資料,但是如果從奇數地址開始的地址存放,就需要兩個讀周期,並對兩次讀出的結果的高低位元組進行拼湊才能得到這個int資料,這樣明顯降低了讀取的效率。

(3)如何進行位元組對齊

每個成員按其類型的對齊參數(通常是這個類型的大小)和指定對齊參數(不指定則取預設值)中較小的一個對齊,並且結構的長度必須為所用過的所有對齊參數的整數倍,不夠就補空位元組。

這個規則有點苦澀,可以把這個規則分解一下,前半句的意思先獲得對齊值後與指定對齊值進行比較,其中對齊值獲得方式如下:

1. 資料類型的自身對齊值為:對於char型資料,其自身對齊值為1,對於short型為2,對於int, long, float類型,其自身對齊值為4,對於 double 類型其自身對齊值為8,單位為位元組。

2.結構體自身對齊值:其成員中自身對齊值最大的那個值。

其中指定對齊值獲得方式如下:

#pragma pack (value)時的指定對齊值value。

未指定則取預設值。

後半句的意思是主要是針對於結構體的長度而言,因為針對資料類型的成員,它僅有一個對齊參數,其本身的長度、於這個對齊參數,即1倍。對於結構體而言,它可能使用了多種資料類型,那麼這句話翻譯成對齊規則: 每個成員的起始地址 % 自身對齊值 = 0,如果不等於 0 則先補空位元組直至這個運算式成立。

換句話說,對於結構體而言,結構體在在記憶體的存放順序用如下規則即可映射出來:

(一)每個成員的起始地址 % 每個成員的自身對齊值 = 0,如果不等於 0 則先補空位元組直至這個運算式成立;

(二)結構體的長度必須為結構體的自身對齊值的整數倍,不夠就補空位元組。

舉個例子:

#pragma pack(8)
struct A{
char a;
long b;
};

struct B{
char a;
struct A b;
long c;
};

struct C{
char a;
struct A b;
double c;
};

struct D{
char a;
struct A b;
double c;
int d;
};

struct E{
char a;
int b;
struct A c;
double d;
};

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。