[問題] 發生 EXCEPTION_DATATYPE_MISALIGNMENT

看板C_and_CPP (C/C++)作者 (我愛阿蓉)時間14年前 (2012/02/13 15:34), 編輯推噓3(3032)
留言35則, 4人參與, 最新討論串1/2 (看更多)
大家好 今天郁到一個奇怪的exception 在非pc 平台的windows環境 wince 但我不知道我哪裡寫錯了@@ 我的程式碼大概寫這樣~ char *RealBuffer = new char[sizeof(int) + sizeof(long long) + sizeof(bool)+ sizeof(double)]; int *pIntPtr = NULL; long long *pLongLongPtr = NULL; bool *pBoolPtr = NULL; double *pDoublePtr = NULL; pIntPtr = reinterpret_cast<int*>(RealBuffer); *pIntPtr = 123; pIntPtr++; pBoolPtr = reinterpret_cast<bool*>(pIntPtr); *pBoolPtr = true; pBoolPtr++; pLongLongPtr = reinterpret_cast<long long*>(pBoolPtr); *pLongLongPtr = 567LL; pLongLongPtr++; //我發現問題點出下面這幾行~ 上面都沒事!!!!!!!! pDoublePtr = reinterpret_cast<long long*>(pLongLongPtr); *pDoublePtr = 123.456; //我這邊出現exception pDoublePtr++; //利用win32 API把RealBuffer 整塊寫到file =================================================== 這段code 我自己用pc版的vc跑沒啥問題 和 我自己觀念上也覺得並沒有錯 但是跑在那個平台就會出exception 所以我必須去解, 但我根本不知道發生什麼事了.... 於是我就去google找了一下 http://xiaojun123hello.blog.163.com/blog/static/361666562011113102724235/ 我看到第一段他的範例跟我的case有點類似 令我不解的是 if (*pi == 4561321) 這邊 和int i; memcpy(&i, pi, 4); if (i == 4561321) endparse data; 我自己看不出來差異點在哪.....他dereference 取得後sizeof(int) bytes 去解釋成int 跟他用memcpy 複製一份 差異在哪 反而感覺多複製了一次.... 而且google過程中 常常會寫說這exception 很常見@@ 我從來沒遇過好像經歷很少... 煩請各位有經驗的版友給予指點 該怎麼寫才是正確的方式 可攜的方法 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.147.15.66 ※ 編輯: QQ29 來自: 122.147.15.66 (02/13 15:38) ※ 編輯: QQ29 來自: 122.147.15.66 (02/13 15:40)

02/13 16:16, , 1F
大部份平台讀取aligned memory address效能會比較好
02/13 16:16, 1F

02/13 16:17, , 2F
因此讀取特定型別的資料時會使用aligned access
02/13 16:17, 2F

02/13 16:17, , 3F
但這類指令吃到unaligned address就會exception了
02/13 16:17, 3F

02/13 16:23, , 4F
我記得api struct 裡面有些欄位為了要 aligned,最後會
02/13 16:23, 4F

02/13 16:24, , 5F
塞一些garbge進去,如char reserve1[3]、reserve2[7] 等
02/13 16:24, 5F

02/13 16:24, , 6F
當然有些塞 char reserve[] 是真的為了以後擴充保留的.
02/13 16:24, 6F

02/13 16:36, , 7F
可是我只是一般primitive type~這樣會出錯的話 該怎辦@@
02/13 16:36, 7F

02/13 16:37, , 8F
且~我還是不清楚他這兩者差億在哪.....滿怪的~
02/13 16:37, 8F

02/13 16:48, , 9F
換句話說我這樣寫是不好的寫法?? 那正規該怎寫呢?
02/13 16:48, 9F

02/13 17:05, , 10F
我上述只是想表達,或許學某些api struct,塞 char[] 避
02/13 17:05, 10F

02/13 17:06, , 11F
開 struct aligned 問題。
02/13 17:06, 11F

02/13 18:57, , 12F
你是把allocate到了記憶體硬轉成double*再去存取
02/13 18:57, 12F

02/13 18:57, , 13F
allocate的時候他又不知道你要拿來當double用
02/13 18:57, 13F

02/13 18:59, , 14F
因為你寫的是 new "char"
02/13 18:59, 14F

02/13 19:01, , 15F
你想讓這些資訊存在同一份空間,為什麼不用union?
02/13 19:01, 15F

02/13 19:50, , 16F
請問l大 我這樣存取這塊我配置的空間 還需要注意原來的type
02/13 19:50, 16F

02/13 19:51, , 17F
是什麼嗎? 但是我有必要一定要這樣作@@
02/13 19:51, 17F

02/13 19:52, , 18F
我是想把這塊mem整個寫到file ~ 請問該怎麼改才是正解呢
02/13 19:52, 18F

02/13 20:23, , 19F
宣告一個struct 第一個成員放union
02/13 20:23, 19F

02/13 20:24, , 20F
自己額外宣告其它成員讓struct大小符合需求
02/13 20:24, 20F

02/13 20:25, , 21F
此外還要用 #pragma pack 避免 compiler 加 padding
02/13 20:25, 21F

02/13 23:28, , 22F
謝謝l大, 所以這才是標準做法嗎? 我以為我這樣寫 看起來沒錯
02/13 23:28, 22F

02/13 23:29, , 23F
我觀念是出在以為dereference下去是合法記憶體就不會發生錯誤
02/13 23:29, 23F

02/13 23:29, , 24F
這觀念是錯的嚕? 所以這是常見的新手問題嗎....
02/13 23:29, 24F

02/13 23:30, , 25F
雖然跟union不是很熟悉 但我會去查一下該怎麼寫~
02/13 23:30, 25F

02/13 23:31, , 26F
因為我在想我這種用途的寫法 應該在image的loader or saver
02/13 23:31, 26F

02/13 23:32, , 27F
應該會使用到吧?(沒自己寫過) 不知道他們怎麼寫的
02/13 23:32, 27F

02/14 01:34, , 28F
想不通上面那篇也是malloc比較大的空間,轉型硬用,怎不會有
02/14 01:34, 28F

02/14 01:36, , 29F
此類問題,上面我問的那篇@@
02/14 01:36, 29F

02/14 09:33, , 30F
應該不是標準的問題,應該是你硬轉的問題,double,char能
02/14 09:33, 30F

02/14 09:34, , 31F
的資料大小本來就不同.
02/14 09:34, 31F

02/14 10:39, , 32F
可是我new的空間是夠的,不太知道為啥這樣寫會壞
02/14 10:39, 32F

02/14 10:40, , 33F
我上一篇j 大範例也是new一段後硬轉確成功
02/14 10:40, 33F

02/14 10:41, , 34F
差別不是很清楚,且這篇只有死在double, long long
02/14 10:41, 34F

02/14 10:42, , 35F
也是8byte怎都沒事@@
02/14 10:42, 35F
文章代碼(AID): #1FEBqVuE (C_and_CPP)
文章代碼(AID): #1FEBqVuE (C_and_CPP)