C 中的資料對齊示例詳解

2022-09-25 03:21:10 字數 1874 閱讀 7106

對於c/c++程式設計師來說,掌握資料對齊是很有必要的,因為只有了解了這個概念,才能知道編譯器在什麼時候會偷偷的塞入一些位元組(padding)到我們的結構體(struct/class),也唯有這樣我們才能更好的理解、優化結構體和記憶體。

看看幾個簡單的stwww.cppcns.comruct,能猜出他們的size嗎?(執行於64bit win10 vs2017)

struct a

;struct b

;struct c

;struct d

;struct e

;int main()

先揭曉答案

如果對任何乙個結構體的大小有疑問,那麼這篇文章非常適合你,請接著往下看,我們會解釋資料對齊。

處理器讀取資料的行為

在c/c++中,每種資料型別都有對齊的要求(這個更多是處理器的要求而非語言層面),大家都知道,處理器工作的時候需要資料匯流排(data bus)、控制匯流排(control bus)和位址匯流排(address bus)一起配合工作。而在資料匯流排取資料的時候,處理器為了高效的工作,一次會取4byte或者8byte資料(依系統32bit或者64bit而不同),這就是所謂資料字長(word size)。同時在讀取記憶體的時候,也會從4byte或者8byte邊界開始讀取,這是處理器行為,我們只能尊重不能改變。考慮下面的例子,

struct f

;#include

int main()

它的起始位址輸出是:

0x000000fe8bcffb88

所以在記憶體中可能的排列就是:

zzmjv

讀取資料的時候,每次讀入8btye,8個位元組為乙個讀取單元,就像蒸籠的一格,這樣做的好處是每次可以盡可能多的讀入資料,減少讀取次數。設想,如果一次唯讀入乙個位元組資料,那麼乙個int就需要4次讀取,明顯效率就很低。

編譯器的做法

如果沒有對齊

了解了處理器如何讀取資料的,我們就不難理解編譯器為什麼會做出調整。試想,如果編譯器不在後台做出填充(padding),那麼我們就會遇到這種情況

像這樣的話,訪問i1, c1 都不會有問題,但是訪問i2就會發現,資料散落在不同的蒸籠,原本只需要一次讀取就行的資料,還需要一次額外的資料讀取才行,這就造成了讀取資料的低效,在某些嚴格的cpu,比如arm上面,這種非對齊的資料讀操作甚至會被拒絕。

編譯器對齊

所以,為了讓資料讀取效率最大化,編譯器會選擇犧牲一部分空間來換取效率,他們不會允許i2橫跨兩個讀取單元。在實際中,上面的結構體會是這樣的

可以看出,

所以,在編譯器的作用下,最開始幾個struct實際上擴充套件為,

struct a

;struct b

;struct c

;struct d

;struct e

;對齊的目的是要讓資料訪問更高效,一般來說,資料型別的對齊要求和它的長度是一致的,比如,

這不是巧合,比如short,2對齊保證了short只可能出現在乙個讀取單元的0, 2, 4, 6格,而不會出現在1, 3, 5, 7格;再比如int,4對齊保證了乙個讀取單元可以裝載2個int——在0或者4格。從根本上杜絕了同乙個資料橫跨讀取單元的問題。

可能有人會疑惑了,知道這些對我們工作有什麼幫助嗎?如果僅僅是比較high-level的應用程式程式設計,可能確實感覺不明顯,最多就當成乙個知識點了解一下,但是對於搞比較底層開發的,比如遊戲引擎,或者是在記憶體環境很緊張的情況下開發,比如嵌入式開發,那了解這個有助於在某些情況下節約記憶體。

考慮前面的d和e結構體,他們擁有完全一樣的成員,卻有著不同的結構體大小,就是因為e選擇把對齊要求接近的變數型別放在一起,減小了填充padding的數量從而達到了減小結構體大小的目的。

在設計結構體的時候,這個可以zzmjv作為乙個考量,有一些函式可以幫助我們檢視某個型別的對齊要求,比如visual studio中的__alignof函式。

C語言位元組對齊 資料對齊詳解

c語言位元組對齊資料對齊詳解 一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照 byte 劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙...

資料對齊 C語言 記憶體位元組對齊詳解

一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。2.對齊的作...

資料對齊 C語言 記憶體位元組對齊詳解

修改部分語言錯誤 一 什麼是對齊,以及為什麼要對齊 1.現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是...