結構體中,用指標偏移量訪問結構體元素時。因為結構體要考慮元素的對齊訪問,所以每個元素實際佔的位元組數和自己本身的型別所佔的位元組數不一定完全一樣(譬如char c實際佔位元組數可能是1,也可能是2,也可能是3…)
一般來說,我們用.的方式來訪問結構體元素時,我們是不用考慮結構體的元素對齊的。因為編譯器會幫我們處理這個細節。但是c語言本身是很底層的語言,而且做嵌入式開發經常需要從記憶體角度,以指標的方式來處理結構體及其中的元素,因此還是需要掌握結構體對齊規則。
1.1結構體中元素對齊訪問主要原因是為了配合硬體,也就是說硬體本身有物理上的限制,如果對齊排布和訪問會提高效率,否則大大降低了效率。
1.2記憶體本身是乙個物理器件(ddr記憶體晶元,soc上的ddr控制器),本身有一定的侷限性:如果記憶體每次訪問時按照4位元組對齊訪問,那麼效率是最高的;如果你不對齊訪問效率要低很多。
1.3還有別的很多原因,導致我們需要對齊訪問。譬如cache的快取特性,還有其他硬體(譬如mmu、lcd顯示器)的一些記憶體依賴特性,所以要求記憶體對齊訪問。
1.4對比對齊訪問和不對齊訪問:對齊訪問浪費了記憶體,提高了速度效率;
編譯器本身可以設定記憶體對齊的規則,有以下規則需要記住:
32位編譯器,一般編譯器預設對齊方式是4位元組對齊
舉例:
分析過程:
//首先是整個結構體,整個結構體變數4位元組對齊是由編譯器保證的。
//然後是第二個元素b,因為上乙個元素a本身佔4個位元組,本身就是對齊的。所以留給b的開始位址也是4位元組對齊位址,所以b可以直接放(b放
//的位置就決定了a一共佔4位元組,因為不需要填充)。
//b的起始位址定了後,結束位址不能定(因為可能需要填充),結束位址要看下乙個元素來定。然後是第三個元素c,short型別需要2位元組對齊(short型別元素必須放在類似0,2,4,8這樣的位址處,不能放在1,3這樣的奇數字址處),因此c不能緊挨著b來存放,解決方案是在b之後新增1位元組填充,然後再開始放c。
//當整個結構體的所有元素對齊存放後,還沒結束,因為整個結構體大小還要是4的整數倍
(1)結構體對齊要考慮:結構體整體本身必須安置在4位元組對齊處,結構體對齊後的大小必須是4的倍數(編譯器設定為4位元組對齊時,如果編譯器設定為8位元組對齊,則這裡的4是8)
(2)結構體中每個元素本身都必須對其存放,而每個元素本身都有自己的對齊規則。
(3)編譯器考慮結構體存放時,以滿足以上2點要求的最少記憶體需要的排布來算。
結構體內存對齊
結構體內存對齊 一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這...
結構體內存對齊
一 什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的...
結構體內存對齊
對齊規則 每個特定平台上的編譯器都有自己的預設 對齊係數 也叫對齊模數 程式設計師可以通過預編譯命令 pragma pack n n 1,2,4,8,16來改變這一係數,其中的n就是你要指定的 對齊係數 規則 1 資料成員對齊規則 結構 struct 的資料成員,第乙個資料成員放在offset為0的...