一、什麼是位元組對齊?
計算機中的資料在儲存時並不是按順序儲存,因為在訪問特定的資料型別時通常從特定的記憶體位址開始,所以資料在儲存時特定的型別儲存時從特定的位址開始,比如我們所說的int型別的對齊數是4,意思是儲存這個int型別的變數的位址%4==0,這就是對齊數為4的意思。
二、為什麼要位元組對齊?
位元組對齊是的思想就是以空間換取時間。所以在儲存資料時採取位元組對齊的方式,可以讓cpu在訪存讀取資料時的效率大大提高。如果資料在儲存時是按照順序的方式來儲存的,比如說有些機器在訪存時每次都是從偶位址開始的,如果我們要訪問乙個int型的資料,我們採用位元組對齊的方式話,在32位的系統下我們通過一次訪存就可以讀出這個資料,如果沒有位元組對齊,那麼當這個整形數的起始位址是個奇位址時,我們要訪存兩次才可以完整的讀出這個資料,並且在讀出後還要通過拼接才能拿到這個整形數,相對而言我們採用位元組對齊的方式的效率高。
三、如何正確的理解資料儲存的位址?
在vc6.0下我們寫出這樣乙個程式
在記憶體中的應該是這樣的
可以看到char型的變數的起始位址是0018ff44,int型的變數的起始位址是0018ff40,可以看出這裡的儲存是使用的了位元組對齊的,char後面的三個位元組被浪費掉以保證我們的記憶體對齊。總結出下面幾條規則:
1、c語言中標準資料型別儲存的起始位址是它們長度的整數倍;
2、結構體中每個成員都要位元組對齊;
3、聯合中按它長度最大成員對齊;
4、陣列的首元素只要位元組對齊,剩餘元素肯定位元組對齊。
四、對於結構體資料大小的相關問題(以下例項是在vs下測試)
首先介紹偏移量
偏移量就是結構體成員相對於結構體的位址偏移,第乙個成員對於結構體的偏移量就是0。
所以對於結構體的大小計算有下面結果準則:
1、結構體變數中成員的偏移量必須是成員大小的整數倍
2、結構體大小必須是結構體成員中長度最大的成員的整數倍。
3、對於巢狀的結構體,其中巢狀的結構體的偏移量應該對齊其中長度最大的成員。
#include#includeint main()
; printf("%d\n", sizeof(struct a));
system("pause");
return 0;
}
執行結果:
a的偏移量是0,b的偏移量應該是sizeof(int)的整數倍,所以b的偏移量是從4開始的,所以結構體大小是8,結構體的大小必須是最大長度成員的整數倍,這裡也剛好滿足。
#include#includeint main()
; printf("%d\n", sizeof(struct a));
system("pause");
return 0;
}
結果是:
這個時候前面兩步的計算和上面的那個例子一樣,當存完c是這個時候的總偏移量是8,大小應該是9,但是9並不是最大成員的整數倍,所以往後還要在偏移三個位元組,因此得到結果12.
#include#includeint main()
; char c;
}; printf("%d\n", sizeof(struct a));
system("pause");
return 0;
}
結果是:
這裡有結構體的巢狀,這個時候存完int b之後的偏移是7,這個時候我們應該考慮的是結構體struct b中最大成員,可以看到double是它的最大成員,所以說這個時候的偏移應該是8的整數倍,剛好存它的其實偏移就是8,所以按照上面的規則,我們先計算struct b的大小是16,直接往後偏移16個位元組,完後在存char c,總偏移是24,大小是25,不是
8的整數倍(最大成員),所以往後偏移到31偏移處,大小為32。
************自己設定對齊數*****************
我們可以通過#pragma pack (n) /*指定按n位元組對齊*/
#pragma pack () /*恢復原有對齊數*/
注意是連用的!!!
這些例項是在vs下執行測試,在其他編譯器可能有所不同,具體情況要具體討論!
C語言中的位元組對齊
一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...
C語言中的位元組對齊
一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...
關於c語言中的位元組對齊padding問題
最近的工作中,發現有乙個很奇怪的問題,就是兩個結構體,裡面的字段的值完全是一樣的,但是用memcpy就是不返回0。大致是下面的 輸出是 aa bb bb cc 為什麼設的值都是一樣的,但是memcmp就是返回不一樣呢。memcpy還算是乙個比較常用的函式,特別是在c語言中比較乙個有較多字段的結構體,...