1. 程式人生 > >C/C++資料對齊

C/C++資料對齊

輸出:
size of struct A : 8
size of struct B : 12
size of struct C : 8
size of struct D : 7

 結構體中包含了4位元組長度的int一個,1位元組長度的char一個以及2位元組長度的short一個。加起來所用到的記憶體空間為7個位元組,但實際使用sizeof時發現,結構體之間佔用的記憶體是不一樣的。

 關於對齊有幾個需要說明的:
 (1)資料型別自身的對齊值:基本資料型別的自身對齊值,char型別為1,short型別為2,int,float,double為4;
 (2)指定對齊值:#pragma pack(value)時的指定對齊值value;
 (3)結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值;
 (4)資料成員、結構體和類的有效對齊值:自身對齊值或指定對齊值中較小值。
 對於一個具體的資料結構的成員和其自身的對齊方式,有效對齊值N將最終決定資料存放地址的方式的值,對齊在N上就意味著資料“存放的起始地址%N=0”,

 下面來針對上面的例子進行分析:
 struct B {
  char b;
  int a;
  short c;
 };
 假設B從地址空間0x0000開始,預設的對齊值是4(這裡有個問題想請教大家,我的是64位的核心,但是測試我的預設對齊方式為4),第一個成員變數b的自身對齊值為1,比預設值小所以有效對齊值為1,存放地址0x0000%1=0,第二個成員變數a,自身對齊值為4,存放的起始地址為0x0004到0x0007這個4個連續的位元組空間中,0x0004%4=0,第三個變數c,自身對齊值為2,存放的起始地址為0x0008到0x0009,地址同樣符合要求。結構體B的自身對齊值為變數中的最大對齊值(b)4,(10+2)%4=0,所以0x000A到0x000B也是被結構體B佔用。
 記憶體中的示意圖:
 b - - -
 a a a a
 c c

 #pragma pack(2)
 struct C {
  char b;
  int a;
  short c;
 };
 #pragma pack()
 第一個變數b的自身對齊值為1,指定對齊值為2,有效對齊值為1,b存放在0x0000,a的自身對齊值為4,大於指定對齊值,所有有效的對齊值為2,a佔有的位元組為0x0002、0x0003、0x0004、0x0005四個連續位元組中,c的自身對齊值為2,所以有效對齊值也是2,順序存放在0x0006、0x0007。結構體C的自身對齊值為4,所以有效對齊值為2,8%2=0。
 記憶體中的示意圖:
 b -
 a a
 a a
 c c

 其實想到記憶體中的示意圖一切都會簡單很多。