關於數據對齊問題

今天看面試寶典時遇到一個問題如下:

class A{

public:

double d;

float a;

int b;

char c;

A();

~A();

};

int mian()

{

cout<<sizeof(A);

}

以我對數據對齊的理解,d爲8個字節,那麼a,b,c均佔8個字節,但是實際上是24個字節(在vc中測試的結果)。後來我打印出它的地址發現,&A.d=0x0012ff58,&A.a=0x0012ff60,&A.b=0x0012ff64,&A.c=0x0012ff68;

由此知道,d佔八個字節,而float和int各佔四個字節,但是依據數據對齊原理:對於n字節的元素(n=2,4,8,。。。),它的首地址能被n整除才能獲得最好的性能。所以c只需一個字節即可,但是實際上編譯器爲A.c申請了8個字節。測試如下:

int main()

{

int test1;

A testA;

int test2;

printf("%08x %08x %08x %08x %08x %08x\n",&test2,&AA.d,&AA.a,&AA.b,&AA.c,&test1);

}

執行的結果爲:0x0012ff54 0x0012ff58 0x0012ff60 0x0012ff64 0x0012ff68 0x0012ff70

由於test1、testA、test2等都是局部變量,均在棧中分配,且test1的地址高,而testA的地址較低,以此類推

從結果可以看出,testA的起始地址是0x0012ff58,結束地址爲0x0012ff70,說明結構體A中的c分配了8個字節的空間。

結論:在編譯器爲變量分配內存時,會依據類型大小最大的變量來對齊(如double),如果有比着小的數據類型並且可以遵循數據對齊原理(上面所述)就是說下一個變量的開始地址必須是它本身的n倍才行,可以按找它自己的大小來分配(如int、float加起來真好是8個字節和double對齊),最後雖然c只是佔用一個字節,但是在此結構體中需要和double對齊,所以也佔據8個字節的空間,如果在c的後面加上多個char類型的變量(別超過7個),整個結構體的大小不會變,還是24,或者加入一個int型的變量,整個結構體的大小還是24。有了這些知識後看下面一個例題:

class B{

public:

bool m_bTemp;

int m_nTmep;

bool m_bTemp2;

};

class C{

public:

int m_nTmep;

bool m_bTemp;

bool m_bTmep2;

}

cout<<sizeof(B)<<endl;

cout<<sizeof(C)<<endl;




執行結果爲:

12

8

在內存中的佈局爲:

類B:

| bool l ------ | ------ | ------ |

| --------------int-------------- |

| bool | bool | ------ | ------ |

類C:

| --------------int-------------- |

| bool | bool | ------ | ------ |

另外需要注意的是:char *str=“dafddsfasdfasdf”;

char str2[]="dfadfasdfasdf";

sizeof(str)=4;//僅僅是一個指針大小

sizeof(str2)=14;//包含\0的字符串大小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章