在
c++中位元組對齊主要存在符合型別中:
union
,struct
和class中
先介紹四個概念:
1) 資料型別自身的對齊值:基本資料型別的自身對齊值,等於sizeof(基本資料型別)。
2) 指定對齊值:#pragma pack (value)時的指定對齊值value。
3) 結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
4) 資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中較小的那個值。
有效對齊值n是最終用來決定資料存放位址方式的值,最重要。有效對齊n,就是表示「對齊在n上」,也就是說該資料的"存放起始位址%n=0"。而資料結構中的資料變數都是按定義的先後順序來排放的。第乙個資料變數的起始位址就是資料結構的起始位址。結構體的成員變數要對齊排放,結構體本身也要根據自身的有效對齊值圓整
(就是結構體成員變數占用總長度需要是對結構體有效對齊值的整數倍)
#pragma pack (value)來告訴編譯器,使用我們指定的對齊值來取代預設的。
如#pragma pack (1) /*指定按1位元組對齊*/
#pragma pack () /*取消指定對齊,恢復預設對齊*/
union
就是取整個成員中大的記憶體塊作為整個共用體的記憶體大小
對齊方式為成員中對齊方式最大的成員的對齊方式,
對界取編譯器對界方式與自身大小中較小的乙個
測試程式如下:
#include
#include
using
std::cout;
using
std::endl;
unionu1
; unionu2
; unionu3
; #pragma
pack
(2)//
對界方式
2位元組¨²
unionu4
; unionu5
; #pragma
pack
() //
恢復預設對界方式
void
main()
測試結果如下: 8
16 13
14 13
結論:由於預設是
8位元組對齊, 在
u1 中a為
8位元組,很明顯
u1的大小就為8。
在u2中由於
int為
4位元組,
char為1
個位元組,所以
min(8,max(4,1))=4,以4
位元組對齊,
u2理論為
13個位元組,要以
4位元組對齊的話所以為
16位元組。同理
u3 :
min(
max(1,1),8)=1
,sizeof(u3
)=13
, u4
:min
(max(1,4),2)=2
,sizeof(u4
)=14,u5
:min
(max(1,1),2)=1
,sizeof(u5
)=13.
都是對整個成員所佔記憶體大小的求和。大小僅和成員變數的型別有關還和定義的先後順序有關
舉個例子,乙個結構體如下:
typedef
struct t ;
假設定義了乙個結構體變數
c,在記憶體中分配到了
0x00
的位置,顯然:
對於成員
c.c
無論如何,也是一次暫存器讀入,所以先佔乙個位元組。
對於成員
c.d
是個64
位的變數,如果緊跟著
c.c儲存,則讀入暫存器至少需要
3次,為了實現最少的
2次讀入,至少需要以
4位元組對齊;同時對於
8位元組的原始變數,為了在定址單位上統一,則需要按
8位元組對齊,所以,應該分配到
0x08-0xf
的位置。
對於成員
c.e
是個32
位的變數,自然只需滿足分配起始為整數個
32位即可,所以分配至
0x10-0x13。
對於成員
c.f
是個16
位的變數,直接分配在
0x14-0x16
上,這樣,反正只需一次讀入暫存器後加工,邊界也與
16位對齊。
對於成員
c.g 是個8
位的變數,本身也得一次讀入暫存器後加工,同時對於
1個位元組的變數,儲存在任何位元組開始都是對齊,所以,分配到
0x17
的位置。
對於成員
c.h
是個16
位的變數,為了保證與
16位邊界對齊,所以,分配到
0x18-0x1a
的位置。 最後
, 該結構體的自身對齊值為8(其成員中自身對齊值最大的那個d), 指定的對齊值為預設值8, 故該結構體的有效對齊值為min(8, 8) = 8,
結構體本身也要根據自身的有效對齊值圓整
, 所以
sizeof(t) = 32
再舉個例子,看看在預設對齊規則下,各結構體成員的對齊規則:
typedef
struct a
; //
整個結構體,最長的成員為
4個位元組,需要總長度與
4位元組對齊,所以,
sizeof(a)==12
typedef
struct b
; /* 整個結構體的最大分配成員為
8位元組,所以結構體後面加
5位元組填充,被到
48位元組。 故:
sizeof(b)==48;*/
mysql位元組對齊 C 位元組對齊彙總
一 什麼是位元組對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。二 位元組對齊的原因和...
c 位元組對齊
1.虛函式 如果 classa 有虛函式,編譯器會給每個 classa 物件新增乙個隱藏成員,該隱藏成員儲存了乙個指向虛函式表的指標.所以 sizeof classa 如果比你預想的多了 4 位,不要驚奇,因為多了乙個 size 指標 但是這個隱藏指標是先算還是後算呢?class a int a c...
C 位元組對齊
這篇部落格主要介紹c 位元組對齊的方式 什麼是位元組對齊 現代計算機中記憶體空間都是按照 byte 劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特 定的 記憶體位址 訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接...