1、為什么會產(chǎn)生數(shù)據(jù)對齊問題
8位CPU 當(dāng)然不會產(chǎn)生數(shù)據(jù)對齊問題,當(dāng)CPU發(fā)展到16,32位時,因為CPU的一次內(nèi)存訪問就能取回4個byte(且用32位舉例,這個數(shù)據(jù)理所當(dāng)然的緩存在相應(yīng)的32位寄存器中)——里面可能存儲了4個1byte的數(shù)據(jù),也可能存儲了2個2byte的數(shù)據(jù)……,所以CPU在邏輯上將內(nèi)存單元尋址地址邊界設(shè)置為4的倍數(shù)(如:0,4,8,12……),這是數(shù)據(jù)對齊產(chǎn)生的必要條件之一;另一個原因是程序中使用的數(shù)據(jù)類型并非都是4的倍數(shù),如:char(1byte),short(2byte),int(4byte)等等。讓我們考慮一下一個2byte的的變量在內(nèi)存單元中排布吧:如果這個變量地址為0或1或2,那么CPU一次內(nèi)存訪問就能夠取得你的變量;但如果是3的話,很不幸,CPU還得訪問一次內(nèi)存以取得全部數(shù)據(jù)。
2、舉例說明
struct A {
char m_ch; //1 Byte
char *m_pStr; //4 Byte
}; //sizeof(A)=8,按4對齊
struct B {
char m_ch; //1 Byte
int m_count; //4 Byte
}; //sizeof(A)=8,按4對齊
struct C {
bool m_ok; //1 Byte
char m_name[6];//char 也是 1 Byte,6個char罷了
};
________________________________________結(jié)構(gòu)體成員________________________________
struct X
{
double m_width; //8 Byte
char m_name[6]; //1 Byte per
}; //sizeof(X)=16
struct Y {
int m_no; //4 Byte
X m_x; //X按8對齊,故按8對齊,
}; //sizeof(Y)=8x3=24,提示可將X m_x擴(kuò)展成struct X
struct X2
{
double m_width; //8 Byte
char m_name[9]; //1 Byte per,前8字節(jié)+8字節(jié)中的一個字節(jié)
}; //sizeof(X2)=8+8+8=24
struct X2
{
double m_width; //8 Byte 8x1
char m_name[9]; //占用8+8 8x2 和 8x3
};
struct Y2 {
int m_no; //4 Byte,占用另一個8字節(jié) 8x4
X2 m_x;
}; //sizeof(Y2)=8+8+8+8=32
enum DataType {IntData,CharData,VcharData};
struct Item
{
char ItemNAme[30]; //按4對齊,故是32
DataType ItemType; //enum站4個字節(jié)
char ItemDecr[50]; //按4對齊,所以是52
int ItemLength; //4字節(jié)
};
sizeof(Item) = 32+4+52+4=92
#pragma pack(2) //指定對齊方式是2
enum DataType {IntData,CharData,VcharData};
struct Item
{
char ItemNAme[30]; //30
DataType ItemType; //4
char ItemDecr[50]; //50
int ItemLength; //4
};
sizeof(Item) = 30+4+50+4=88