1、為什么會產生數據對齊問題
8位CPU 當然不會產生數據對齊問題,當CPU發展到16,32位時,因為CPU的一次內存訪問就能取回4個byte(且用32位舉例,這個數據理所當然的緩存在相應的32位寄存器中)——里面可能存儲了4個1byte的數據,也可能存儲了2個2byte的數據……,所以CPU在邏輯上將內存單元尋址地址邊界設置為4的倍數(如:0,4,8,12……),這是數據對齊產生的必要條件之一;另一個原因是程序中使用的數據類型并非都是4的倍數,如:char(1byte),short(2byte),int(4byte)等等。讓我們考慮一下一個2byte的的變量在內存單元中排布吧:如果這個變量地址為0或1或2,那么CPU一次內存訪問就能夠取得你的變量;但如果是3的話,很不幸,CPU還得訪問一次內存以取得全部數據。
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罷了
};
________________________________________結構體成員________________________________
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擴展成struct X
struct X2
{
double m_width; //8 Byte
char m_name[9]; //1 Byte per,前8字節+8字節中的一個字節
}; //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字節 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個字節
char ItemDecr[50]; //按4對齊,所以是52
int ItemLength; //4字節
};
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