所謂內存對齊,是為了讓內存存取更有效率而采用的一種編譯階段優化內存存取的手段。
比如對於int x;(這裡假設sizeof(int)==4),因為cpu對內存的讀取操作是對齊的,如果x的地址不是4的倍數,那麼讀取這個x,需要讀取兩次共8個字節,然後還要將其拼接成一個int,這比存取對齊過的x要麻煩很多。
對於簡單類型,如int,char,float等,其對齊大小為其本身大小,即align(int) == sizeof(int),align(char)==sizeof(char),等等。
對於復合類型,如struct,class,其本身並無所謂對齊,因為CPU沒有直接存取一個struct的指令。對於struct而言,它的對齊指的是它裡面的所有成員變量都是對齊的,class同理。
下面就講講struct對齊是怎麼回事。
首先要明白三個點:
1,內存對齊是指首地址對齊,而不是說每個變量大小對齊;
2,結構體內存對齊要求結構體內每一個成員變量都是內存對齊的;
3,結構體對齊除了第2點之外還要求結構體數組也必須是對齊的,也就是說每個相鄰的結構體內部都是對齊的。
OK,先知道上面這3點之後,開始接觸怎麼算對齊大小。
程序員可自己指定某些數據的對齊大小,通過使用下面的預處理指令,指定對齊大小為x。(這裡需要注意:只能指定2的n次方作為對齊大小,對於指定對齊大小為6,9,10這樣的編譯器可能會不予理會)
#pragma pack(x) //... #pragma pack()
那到現在,可能大家有個疑問了,那對於int(這裡假設sizeof(int)==4),手動指定對齊大小為8,那align(int)是等於sizeof(int)還是等於8呢 ?
這裡大家可以記住,align(x) = min ( sizeof(x) , packalign) , 即sizeof(x)和指定對齊大小哪個小,對齊大小就為哪個。
因此,上面的疑問答案是align(int)=sizeof(int)=4 。
三,怎麼算內存對齊大小(示范)?
#include <cassert> int main(int argc, char* argv[]) { //此處指定對齊大小為1 //對於a,實際對齊大小為min(sizeof(int),1)=min(4,1)=1 //對於b,實際對齊大小為min(sizeof(char),1)=min(1,1)=1 //編譯器會確保TEST_A首地址即a的地首址是1字節對齊的,此時a對齊 //