看板 C_and_CPP 關於我們 聯絡資訊
大家好 今天郁到一個奇怪的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)
littleshan:大部份平台讀取aligned memory address效能會比較好 02/13 16:16
littleshan:因此讀取特定型別的資料時會使用aligned access 02/13 16:17
littleshan:但這類指令吃到unaligned address就會exception了 02/13 16:17
tropical72:我記得api struct 裡面有些欄位為了要 aligned,最後會 02/13 16:23
tropical72:塞一些garbge進去,如char reserve1[3]、reserve2[7] 等 02/13 16:24
tropical72:當然有些塞 char reserve[] 是真的為了以後擴充保留的. 02/13 16:24
QQ29:可是我只是一般primitive type~這樣會出錯的話 該怎辦@@ 02/13 16:36
QQ29:且~我還是不清楚他這兩者差億在哪.....滿怪的~ 02/13 16:37
QQ29:換句話說我這樣寫是不好的寫法?? 那正規該怎寫呢? 02/13 16:48
tropical72:我上述只是想表達,或許學某些api struct,塞 char[] 避 02/13 17:05
tropical72:開 struct aligned 問題。 02/13 17:06
littleshan:你是把allocate到了記憶體硬轉成double*再去存取 02/13 18:57
littleshan:allocate的時候他又不知道你要拿來當double用 02/13 18:57
littleshan:因為你寫的是 new "char" 02/13 18:59
littleshan:你想讓這些資訊存在同一份空間,為什麼不用union? 02/13 19:01
QQ29:請問l大 我這樣存取這塊我配置的空間 還需要注意原來的type 02/13 19:50
QQ29:是什麼嗎? 但是我有必要一定要這樣作@@ 02/13 19:51
QQ29:我是想把這塊mem整個寫到file ~ 請問該怎麼改才是正解呢 02/13 19:52
littleshan:宣告一個struct 第一個成員放union 02/13 20:23
littleshan:自己額外宣告其它成員讓struct大小符合需求 02/13 20:24
littleshan:此外還要用 #pragma pack 避免 compiler 加 padding 02/13 20:25
QQ29:謝謝l大, 所以這才是標準做法嗎? 我以為我這樣寫 看起來沒錯 02/13 23:28
QQ29:我觀念是出在以為dereference下去是合法記憶體就不會發生錯誤 02/13 23:29
QQ29:這觀念是錯的嚕? 所以這是常見的新手問題嗎.... 02/13 23:29
QQ29:雖然跟union不是很熟悉 但我會去查一下該怎麼寫~ 02/13 23:30
QQ29:因為我在想我這種用途的寫法 應該在image的loader or saver 02/13 23:31
QQ29:應該會使用到吧?(沒自己寫過) 不知道他們怎麼寫的 02/13 23:32
QQ29:想不通上面那篇也是malloc比較大的空間,轉型硬用,怎不會有 02/14 01:34
QQ29:此類問題,上面我問的那篇@@ 02/14 01:36
angleevil:應該不是標準的問題,應該是你硬轉的問題,double,char能 02/14 09:33
angleevil:的資料大小本來就不同. 02/14 09:34
QQ29:可是我new的空間是夠的,不太知道為啥這樣寫會壞 02/14 10:39
QQ29:我上一篇j 大範例也是new一段後硬轉確成功 02/14 10:40
QQ29:差別不是很清楚,且這篇只有死在double, long long 02/14 10:41
QQ29:也是8byte怎都沒事@@ 02/14 10:42