以前在單片機上寫一個PPPoE的協議棧,發送的幀中總是多出一個字節,導致協商失敗。抓包發現該字節還是變化的。。。後看來走讀代碼、查看結構,忽然想起,該單片機是16位的,默認按量字節對齊,結構中出現了一個1字節的空洞,發包時把這個空洞也發出去了,後來改成按1字節對齊問題解決。
這是個有意義的經歷。我們在閱讀RFC是會發現,大部分協議報頭都是按4字節對齊的,這在32位的系統上沒有問題。我們似乎不用在乎該細節。可是我們未必一輩子按4字節對齊吧,現在64位的硬件滿大街都是了,以前我反彙編多媒體軟件時發現很多都是按16字節對齊的。所以在處理網路數據時最好顯示聲明一把,默認的配置可能在不經意間變化了,你還搞不清楚問題所在。
經測試,在VC上,只要在結構聲明的前後加上顯示按1字節對齊的預編譯指令就好了,其他部分仍按原有方式對齊,比如有結構A,在頭文件test.h中定義,
test.h
---------------------
...
#pragma pack(1) //強制按一字節對齊
struct A
{
char m1;
int m2;
char m3;
}
#pragma pack() //還原原有對齊方式
...
那麼在test.c中聲明一個A類型的變量時它會自動按一字節對齊的方式構造該變量。
test.c
-----------------
struct stXX; //該結構佔6個字節,在這裡不必使用#pragma pack指令了。
VC下觀察內存已證明。