內容會持續更新,有錯誤的地方歡迎指正,謝謝!
對齊的三個原則
如何記憶體對齊?sizeof的結果怎麼來的?請記住以下3條原則:(在沒有#pragma pack巨集的情況下)
原則1:結構(struct)或聯合(union)的資料成員,儲存的起始位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,比如說是陣列,結構體等)的整數倍開始(比如:假設乙個資料成員為int,int在32位機上為4位元組,則要從4的整數倍位址開始儲存)
原則2:如果乙個結構裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存。(比如:struct a裡存有struct b,b裡有char,int ,double等元素,那b應該從8的整數倍開始儲存)
原則3:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。
記憶體位元組對齊的原因
根本原因在於cpu訪問資料的效率問題。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那麼乙個讀週期就可以讀出這32bit,而如果存放在奇位址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit資料。顯然在讀取效率上下降很多。
舉例1
typedef
struct bb
bb;typedef
struct aa
aa;int main()
結果是48 24
舉例2
在32位cpu上選擇預設對齊的情況下,有如下結構體定義:
struct a
;
則sizeof(struct a)的值為?
解答:由32位預設對齊,所以有:
由於19+11=30<32,19和11算作32位,即4個位元組
由於4+29>32,4算作32位,即4個位元組
由於29+8>32,29算作32位,即4個位元組
由於8<32,8算作32位,即4個位元組
所以,總共有16個位元組!sizeof(struct a)的值為16。
用pragma控制記憶體對齊
再講講#pragma pack():在**前加一句#pragma pack(1),你會發現上面的**輸出為32 16,因為bb是4+8+4=16,aa是2+4+8+2+16=32。這不就是理想中的沒有記憶體對齊的世界嘛。
下面的**,在#pragma pack(4)
和#pragma pack(8)
的情況下,結構體的大小分別是:
所以,答案為16,16,16,24
什麼是位元組對齊,為什麼要對齊
什麼是位元組對齊,為什麼要對齊?現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和...
什麼是位元組對齊,為什麼要對齊
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的處...
什麼是位元組對齊,為什麼要對齊
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各個硬體平台對儲存空間的處...