結構體的對齊訪問
1、結構體中元素的訪問其實本質還是用指標方式,結合這個元素在整個結構體中的偏移量和這個元素的型別來進行訪問的。
2、每個元素實際佔的位元組數和自己本身的型別所佔的位元組數不一定完全一樣。(譬如char c實際佔位元組數可能是1,也可能是)
2,也可能是3,也可能是4)
3、一般來說,我們用.的方式來訪問結構體元素時,我們是不用考慮結構體的元素對齊的。因為編譯器會幫我們處理這個細節。
但是c語言本身是很底層的語言,而且做嵌入式開發經常需要從記憶體角度,以指標方式來處理結構體及其中的元素,因此還是需要掌握
結構體對齊規則。
4、結構體中元素對齊訪問主要原因是為了配合硬體,也就是說硬體本身有物理上的限制,如果對齊排布和訪問會提高效率,否則
會大大降低效率。
5、記憶體本身是乙個物理器件(ddr記憶體晶元,soc上的ddr控制器),本身有一定的侷限性:如果記憶體每次訪問時按照4位元組對其訪問,
那麼效率是最高的;如果不對齊訪問效率要低很多。
6、對齊訪問犧牲了記憶體空間,換取了速度效能;而非對齊訪問犧牲了訪問速度效能,換取了記憶體空間的完全利用。
7、編譯器本身可以設定記憶體對齊的規則,有以下的規則需要記住:
第乙個:32位編譯器,一般編譯器預設對齊方式是4位元組對齊。
8、結構體對齊的分析要點和關鍵:
(1)結構體對齊要考慮:結構體整體本身必須安置在4位元組對齊處,結構體對齊後的大小必須是4的倍數。(編譯器設定為8位元組對齊時,則這裡的4是8)。
(2)結構體中的每個元素本身都必須對齊存放,而每個元素本身都有自己的對齊規則。
(3)編譯器考慮結構體存放時,以滿足以上2點要求的最少記憶體需要排布來算。
舉例說明:
struct mystruct1
分析過程:
首先是整個結構體,整個結構體變數是4位元組對齊是由編譯器保證的,我們不用操心。
(1)然後是第乙個元素a,a的開始位址就是整個結構體的起始位址,所以自然是4位元組對齊,但是a的結束位址是由下乙個元素說了算。
(2)然後是第二個元素b,因為上乙個元素a本身佔4個位元組,本身是對齊的,所以留給b的起始位址也是4位元組對齊位址,所以b可以直接放
(b的位置就決定了a一共佔4個位元組,因為不需要填充)。
(4)然後就是第三個元素c,short型別的需要2個位元組對齊(short型別的元素必須放在類似0,2,4,8這樣的位址處,不能放在1,3這樣的
奇數字址處),因此c不能緊挨著b來存放,解決方案就是b之後新增1位元組的填充,然後開始存放c。c放完之後還沒結束,因為整個結構體的
大小還要是4的整數倍,可能還需要填充,也可能不需要。
9、設定結構體對齊位數的指令:__attribute__((packed)) __attribute__((aligned(n)))
#pragma pack();1位元組對齊 #pragma pack(4);4位元組對齊
5 5結構體的對齊訪問
1 上一節講過結構體中元素的訪問其實本質上還是用指標方式,結合這個元素在整個結構體中的偏移量和這個元素的型別來進行訪問的。2 但是實際上結構體的元素的偏移量比我們上一節講的還要複雜,因為結構體要考慮元素的對齊訪問,所以每個元素實際佔的位元組數和自己本身的型別所佔的位元組數不一定完全一樣。譬如char...
結構體的對齊
個人理解,如有誤,請指正。一 結構體內成員的的對齊 成員的位址要按照成員的大小來對齊 比如int 型別的資料的位址要按照sizeof int 對齊 比如 typedef struct s s sizeof s 8 除了要考慮結構體內成員的位址對齊 還要考慮結構體自身的對齊,原因就是因為當多個結構體成...
結構體對齊
現在去掉第乙個成員變數為如下 pragma pack 4 class testc int nsize sizeof testc 按照正常的填充方式nsize的結果應該是8,為什麼結果顯示nsize為6呢?事實上,很多人對 pragma pack的理解是錯誤的。pragma pack規定的對齊長度,實...