為什麼要位元組對齊?
位元組對齊實際上是犧牲空間換取時間的行為;
為了解決cpu訪問資料的效率問題;cpu訪問資料都會讀取固定字長的資料,例如32位cpu,一次性會讀取32bit的資料;
例如:第一次會讀取0x0000, 0x0001, 0x0002, 0x0003 這四個位址空間內的資料(每個位址存著1位元組的資料),總共4位元組,即32位的資料;
第二次會讀取0x0004, 0x0005, 0x0006, 0x0007 這四個位址空間內的資料;
假設有乙個變數的大小為4個位元組;
如果存放在0x0002, 0x0003, 0x0004, 0x0005這四個位址空間中,那麼cpu訪問該變數時,就需要讀兩次;
如果存放在0x0004, 0x0005, 0x0006, 0x0007這四個位址空間中,那麼cpu訪問該變數時,就需要讀一次;
也就是說變數的起始位址要天然能被字長整除;0x0004%4=0; 換種說法就是位元組對齊;
一些平台讀取資料的位址都是從特定的位址開始訪問的,例如從偶位址開始訪問;
如果資料存放的起始位址跟讀寫起始位址一致,就會有效減少訪問次數,從而節約時間,提公升效率;
起始位址要符合自然邊界條件;這個條件是指其起始位址值和資料長度的關係;整數倍關係;start_addr % data_len = 0
結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
指定對齊值:#pragma pack (value)時的指定對齊值value。
資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值。
預設對齊值:結構體中每個資料成員及結構體本身都有預設對齊值,記為defaultlen;
指定對齊值:**中指定的對齊值,記為packlen;
成員偏移量:每個成員相對於結構體起始位置的長度,記為offset;
成員長度:結構體中每個資料成員的長度(注結構體成員為補齊之後的長度),記為memberlen。
對齊規則: offset % vaildlen = 0,其中vaildlen為有效對齊值,vaildlen = min(packlen, defaultlen);
填充規則: 如成員變數不遵守對齊規則,則需要對其補齊;在其前面填充一些位元組保證該成員對齊。需填充的位元組數記為pad
在linux中2位元組資料型別(例如short)的位址必須是2的倍數,而較大的資料型別(例如int,int *,float和double)的位址必須是4的倍數。
也就是說linux下要麼2位元組對齊,要麼4位元組對齊,沒有其他格式的對齊。
c語言位元組對齊:
RTEMS作業系統概念 位元組對齊
現代計算機中記憶體空間都是按照位元組 byte 劃分的。從理論上講似乎對記憶體的訪問可以從任何位址開始,但現實是儲存在某些特別位址上的資料需要多次訪問,經過特殊處理後才能訪問到。為了提高訪問速度,需要資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是位元組對齊 byte align...
位元組順序 位元組對齊
一.位元組順序的產生 在計算機中,資料是以位元組為單位存放的,而c語言中只有char才是乙個位元組,其他如int,float都是大於乙個位元組,所以就存在將資料按怎樣的順序存放的問題。一般有大端序和小端序兩種方式,特殊的還有混合序,也就是兩種存放方式同時存在於乙個計算機系統中。上面講的都是主機位元組...
位元組順序 位元組對齊
一.位元組順序的產生 在計算機中,資料是以位元組為單位存放的,而c語言中只有char才是乙個位元組,其他如int,float都是大於乙個位元組,所以就存在將資料按怎樣的順序存放的問題。一般有大端序和小端序兩種方式,特殊的還有混合序,也就是兩種存放方式同時存在於乙個計算機系統中。上面講的都是主機位元組...