當前位置:
首頁 >
关于内存对齐
發布時間:2025/7/14
32
豆豆
?
??? 曾經接手一個網絡視頻監控程序,主要是上層軟件通過發送控制指令獲取網絡視頻板的視頻數據和控制網絡視頻板,這應該是一個比較簡單的流程!
一切的開發都很順利,測試的時候,問題就來了,獲取視頻數據流的數據竟然是錯誤的,我糊涂了,把整個程序流程,用調試器一步一步地跑,到了發送視頻指令的時候,返回指令操作錯誤的結果,怎么回事?我是按照視頻的操作指令封裝的數據包,內存顯示數據包的內容是沒有錯誤的,就是一個晚上,我不停地找"錯誤",只有偶然,我把sizeof()這個指令直接換掉,把數據包全部用一個BYTE的數據進行copy,程序成功執行!這時,我已經快暈了!
數據發送到網絡板的數據包大小根本不是實際控制數據包的大小!
這時我才想起一個人, Stanley B. Lippman,他寫的那一本書 "Inside object modale", 曾經提過這樣的事情,編譯器為了提高CPU的效率,會對struct 的結構進行優化,利用sizeof 可以得出不同的計算機上對 struct 的結構優化后的大小值.以前是看過,但是,卻沒有深刻理會,現在,吃了苦頭,才明白!
這是我的理解,C++ 編譯器為了使CPU的性能達到最佳,會對 struct 的內存結構進行優化,這是為了達到CPU數據傳輸總線的吞吐值,各個計算機的數據傳輸總線是不一樣的,如32位的計算機的數據傳輸值是4 bytes,64位計算機數據傳輸是8 bytes,這樣,struct 在默認的情況上,編譯器會對 struct 的結構進行數據對齊((32位機)4的倍數或(64位機)8的倍數),如下面這段代碼所示:
#include typedef struct tagPACKAGE {int intValue;char chValue1;char chValue2; } PACKAGE, * LP_PACKAGE;int main() {PACKAGE package;std::cout << "sizeof( package ) = " << sizeof( package ) << std::endl;return 0; }
程序執行結果為 8 ( sizeof( int ) + sizeof( char ) + sizeof( char ) + 對齊值 )為8. (我的機子是32位,4*2=8)一切都是編譯器搞得自已頭暈,但是為什么以前自已寫的網絡程序沒有這種情況?同樣的數據包傳輸,我并沒有阻止編譯進行強制對齊,我猜可能是操作系統都是一樣(都是WinX系統)的才沒有出現問題,而現在的網絡視頻板是內嵌式linux,對數據包的處理是純數據(不經對齊的數據)是敏感的所以,才會出現這樣的問題!這種情的解決方法是阻止編譯器對數據包對齊,因為數據對齊的時候,編譯器會塞入一些沒有意義的數據對結構進行對齊,使用#pragma 強制編譯器產生指定數據對齊方式,如下代碼所示
#pragma pack(push) #pragma pack(1) typedef struct tagPACKAGE {int intValue;char chValue1;char chValue2; } PACKAGE, * LP_PACKAGE; #pragma pack(pop)typedef struct tagPACKAGE2 {int intValue;char chValue1;char chValue2; } PACKAGE2, * LP_PACKAGE2;int main() {PACKAGE package;PACKAGE2 package2;std::cout << "sizeof( package ) = " << sizeof( package ) << std::endl;std::cout << "sizeof( package2 ) = " << sizeof( package2 ) << std::endl;return 0; }
對指定的數據包編譯時進行內存對齊,這樣,也不會讓編譯器對其數據進行優化!
總結:
C++的編譯器總是在背后做了很多事!網絡數據處理或與內嵌式設備打交道的時候,這更應該小心!
轉載于:https://www.cnblogs.com/javaspring/archive/2012/04/13/2656151.html
總結
- 上一篇: native-maven-plugin与
- 下一篇: html长文本自动换行