[問題] struct的field位址出錯

看板C_and_CPP作者 (df)時間14年前 (2011/09/24 00:53), 編輯推噓5(5022)
留言27則, 5人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) ARM GCC 我有一筆raw data要parse 假設raw data如下: C0 03 6F 44 01 我定義一個struct為 typedef struct { unsign char Tag; unsign char Len; unsign short Add; unsign char ID; }Tlv_s; 並宣告變數 Tlv_s * tlvPtr; 並指向raw data第一個byte的位址 接著 printf("Tag = %x, Len = %x, Add = %x\n",tlvPtr->Tag,tlvPtr->Len,tlvPtr->Add); 得到的結果是 Tag = C0, Len = 3, Add = 6F03 請問為什麼不是 Tag = C0, Len = 3, Add = 446F 我想問的是觀念的問題, 程式就不詳細描述了 另外補充幾點: 1. 同樣一份code我用vc++跑就會出現 Add = 446F 2. 在我的工作平台上重複parse幾筆raw data 則有的出現第一種情形,有的出現第二種情形 每次跑每次結果都一樣,也就是出現第一種情形的data永遠出現第一種,第二種也是 這個問題困擾我很久, 甚至不知道該怎麼找答案... 感覺就是遇到鬼了...... 期望有高手能相救 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.43.132.205

09/24 01:07, , 1F
在我的電腦上跑出 Tag = c0, Len = 3, Add = 446f 耶..XD
09/24 01:07, 1F

09/24 01:10, , 2F
我猜是因為 http://ppt.cc/WcM1 造成的
09/24 01:10, 2F

09/24 01:10, , 3F
在上面那個網頁找一下 #pragma pack(1) 的用法
09/24 01:10, 3F

09/24 01:43, , 4F
但是alignment應該不會有忽前忽後的問題
09/24 01:43, 4F

09/24 02:06, , 5F
raw data是這樣連續一堆的5 bytes這樣嗎? 小弟猜把每筆
09/24 02:06, 5F

09/24 02:06, , 6F
raw的頭的address印出來看說不定會找到出現第一種與第二
09/24 02:06, 6F

09/24 02:06, , 7F
種狀況時, address有相似的特徵....@_@"
09/24 02:06, 7F

09/24 02:10, , 8F
印象中好像板上哪位大大寫過, pointer沒有指到對齊其型
09/24 02:10, 8F

09/24 02:11, , 9F
態的address時, compiler可能會做出出乎預期的mem
09/24 02:11, 9F

09/24 02:11, , 10F
dereference取值方式....@_@"
09/24 02:11, 10F

09/24 02:12, , 11F
看這情形, 像是Add(short)剛好對應到像0x10000003這種沒
09/24 02:12, 11F

09/24 02:13, , 12F
與short對齊的address時, 自動被解到0x10000002去了@_@"
09/24 02:13, 12F

09/24 02:31, , 13F
arm 平台的特性相關吧? (不懂這塊)
09/24 02:31, 13F

09/24 02:34, , 14F
把asm與mem的部份全開出來一筆一筆step比對來查XD
09/24 02:34, 14F

09/24 02:35, , 15F
其實我也是瞎猜的,直覺就想到alignment跟padding
09/24 02:35, 15F

09/24 02:39, , 16F
至少先鎖定一個症狀, 不是的話再想其他的可能.
09/24 02:39, 16F

09/24 16:21, , 17F
也對...不然就jtag直接看吧
09/24 16:21, 17F

09/24 22:59, , 18F
我之前讀address出來位址其實是正確的
09/24 22:59, 18F

09/24 23:00, , 19F
也就是&(tlvPtr->Add)的確指向6F的位址
09/24 23:00, 19F

09/24 23:02, , 20F
但讀tlvPtr->Add的值卻會出錯
09/24 23:02, 20F

09/24 23:06, , 21F
請問一下Victor,像這種情形有辦法預防嗎? 因為這蠻常用的
09/24 23:06, 21F

09/25 17:29, , 22F
不, 指看只向的位址是6F的位址還不夠, 把pass與fail的
09/25 17:29, 22F

09/25 17:29, , 23F
address本身貼出來看看, 才知道是不是小弟猜測的狀況.
09/25 17:29, 23F

09/25 17:33, , 24F
如果是小弟猜的狀況, 不知道先alloc一個Tlv_s aligned的
09/25 17:33, 24F

09/25 17:34, , 25F
temp memory, 然後raw的每一筆都先當成5byte的char arr
09/25 17:34, 25F

09/25 17:34, , 26F
copy進那塊temp, 然後parser在對該temp memory來parse.
09/25 17:34, 26F

09/25 17:35, , 27F
只是不知道會不會被compiler optimize掉中間這一步Orz
09/25 17:35, 27F
文章代碼(AID): #1EVBcaIO (C_and_CPP)
文章代碼(AID): #1EVBcaIO (C_and_CPP)