結構體成員對齊的問題
現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。
(1)現象
比如有些平臺每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那麼一個讀週期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit資料。顯然在讀取效率上下降很多。看下面一個例子:
32位機上,預設4位元組對齊
struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
main()
{
struct A x;
struct B y;
printf("%d %d", sizeof(x),sizeof(y));
}
得到的結果是8,12。按理說兩者應該一樣是7才對?之所以出現上面的結果是因為編譯器要對資料成員在空間上進行對齊。對A,a佔4位元組,b佔一位元組,c佔兩位元組,b、c可以放在一個4位元組裡面,且最小分配是4,所以共佔8;對B,b佔一位元組,但它容納不了a了,所以a要佔另外4位元組,b只能單佔4位元組,後面的c也只能單佔4位元組,也即沒有共用的,所以佔12。可見次序是有影響的。
上面是按照編譯器的預設設定進行對齊的結果,那麼我們是不是可以改變編譯器的這種預設對齊設定呢?當然可以。
#pragma pack(2)
struct B
{
char b;
int a;
short c;
};
int _tmain()
{
B y;
printf("%d ",sizeof(y));
}
輸出是8,因為是2位元組對齊最小可以2位元組分配,b佔兩位元組,a佔4位元組,c佔2位元組。類似的還有如下:
#pragma pack(1)
struct B
{
char b;
int a;
short c;
};
int _tmain()
{
B y;
printf("%d ",sizeof(y));
}
輸出是7,因為1位元組對齊,最小可以分配1。那麼b佔一位元組,a佔4位元組,c佔2位元組。
(2)原則歸納
綜合如下,對齊的原則:
1,資料型別自身的對齊值:對於char型資料,其自身對齊值為1,對於short型為2,對於int,float,double型別,其自身對齊值為4,單位位元組。
2,結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值。
3,指定對齊值:#pragma pack (value)時的指定對齊值value。
(3)如何使用
如何修改編譯器的預設對齊值?
1,在VC IDE中,可以這樣修改:[Project]|[Settings],c/c++選項卡Category的Code Generation選項的Struct Member Alignment中修改,預設是8位元組。
2,在編碼時,可以這樣動態修改:#pragma pack 。
3,如果在程式設計的時候要考慮節約空間的話,那麼我們只需要假定結構的首地址是0,然後各個變數按照上面的原則進行排列即可。基本的原則就是把結構中的變數按照型別大小從小到大宣告,儘量減少中間的填補空間。還有一種就是為了以空間換取時間的效率,比如:有一種使用空間換時間做法是顯式的插入reserved成員:
struct A{
char a;
char reserved[3];//使用空間換時間
int b;
}
reserved成員對我們的程式沒有什麼意義,它只是起到填補空間以達到位元組對齊的目的,當然即使不加這個成員通常編譯器也會給我們自動填補對齊,我們自己加上它只是起到顯式的提醒作用。
轉自http://blog.csdn.net/sky0829/article/details/6010482
相關文章
- C語言中結構體struct的對齊問題C語言結構體Struct
- C結構體中資料的記憶體對齊問題結構體記憶體
- 結構體內部儲存中的對齊問題結構體
- 關於C語言結構體對齊問題的探討C語言結構體
- 結構體記憶體對齊結構體記憶體
- C 語言結構體的對齊原則結構體
- c 結構體記憶體對齊詳解結構體記憶體
- C++ struct結構體記憶體對齊C++Struct結構體記憶體
- C/C++結構體對齊測試C++結構體
- 已知結構體成員地址獲取結構體首地址結構體
- struct結構體大小的計算(記憶體對齊)Struct結構體記憶體
- 從 CPU 角度理解 Go 中的結構體記憶體對齊Go結構體記憶體
- 結構體問題結構體
- 結構體的sizeof問題結構體
- 小心C#中的只讀結構體成員C#結構體
- C/C++ 結構體位元組對齊詳解C++結構體
- Windows+GCC下記憶體對齊的常見問題WindowsGC記憶體
- C語言兩結構體之間的成員互換C語言結構體
- 由結構體對齊所引發的對C++類物件記憶體模型的思考(一)結構體C++物件記憶體模型
- 由結構體對齊所引發的對C++類物件記憶體模型的思考(二)結構體C++物件記憶體模型
- c++記憶體中位元組對齊問題詳解C++記憶體
- c/c++資料對齊問題C++
- C# 8: 可變結構體中的只讀例項成員C#結構體
- 結構體三種例項化方法(含成員函式)結構體函式
- 使用__attribute__處理對齊問題
- <摘錄>位元組對齊與結構體大小結構體
- 軟體架構:問題起源和應對架構
- 創業團隊成員的「挑戰」以及「成長」的問題創業團隊
- 記憶體對齊記憶體
- Atom外掛aligner冒號(:)對齊的問題
- WPS/Word中公式與文字不對齊的問題公式
- 對於靜態成員來說是類的建構函式,對於例項成員是類的原型物件。函式原型物件
- 飛行員配對方案問題
- C++ protected許可權成員以及類和結構體區別C++結構體
- 面試題:JVM在Java堆中對物件的建立、記憶體結構、訪問方式面試題JVMJava物件記憶體
- 新成員,新問題(介面卡模式)模式
- iOS上如何讓按鈕文字左對齊問題iOS
- GO 記憶體對齊Go記憶體