Re: [問題] delete與堆積損毀

看板C_and_CPP (C/C++)作者 (我愛阿蓉)時間13年前 (2012/12/27 15:39), 編輯推噓4(4037)
留言41則, 5人參與, 最新討論串2/2 (看更多)
因為之前有問一些關於delete的問題 但還是有個盲點 想藉此問下 http://codepad.org/EWq537FI 我知道我存取超過配置範圍 1. 為啥只有在delete 時間點才會觸發程式"壞掉"...? - 之前問問題有被糾正過觀念 OS是紀錄配置的起始位址跟長度 那我現在多存取的部分 照字面上OS是不曉得的阿? 他怎知道我多存取了? 至於壞掉的原因是什麼? 2. 上面用"壞掉" 是因為我不曉得這種是甚麼型態的東西 我__try __except都抓不到他... 用release build跑也直接當掉.. 從VC的dialog又不知道該怎麼error handling 還是這種就是死當沒有他法? VC這dialog還有一些奇怪選項可以勾... 都不知道在幹嘛= = 謝謝 ※ 引述《la8day (la8day)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : VC++ 2008 : 問題(Question): : 用new配置一個array後,然後delete。但VC此時跳出來說已觸發中斷點,堆積損毀等等 : 爬文+google之後發現也有人有類似情況,但初學不久,檢查code老半天還是看不出來 : 哪裡有問題.... : 我把code簡化了,原本的I/O、功能應該不太重要 : 問題應該就是出在那個*setPoly : 如果把delete [] setPoly那邊註解掉,或是把那個for迴圈的內容也砍了就不會有問題 : 不過我想這code已經這麼短了....debug很久還是不得其解囧 : 程式碼(Code):(請善用置底文網頁, 記得排版) : void readIO(int argc, char *argv[]) : { : int *setPoly=0; : int i; : int j=5; : Icount = 8; : Ocount = 4; : Pcount = 5; : NUM_PRT = 17; : setPoly = new int (1000); : cout<<"Pcount ="<<Pcount<<endl; : for(i=0;i<Pcount;i++) : { : *(setPoly+i) = j; : cout<<"setPoly->"<<*(setPoly+i)<<endl; : } : delete [] setPoly; : } : 補充說明(Supplement): : 原本int *setPoly我是設成全域變數,而且是在main去釋放他 : 但後來改成區域變數且在同個function釋放也是同樣問題,我想應該無關? : 明顯是*setPoly在作怪,不釋放記憶體就可以正常執行。但到了其他function可能會 : 繼續造成危害。 : 這code和問題好像都沒啥程度> <,不過已經困擾頗久,還請各位高手來解惑~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.163.58.205

12/27 15:58, , 1F
undefined behavior不代表他要壞掉給你看
12/27 15:58, 1F

12/27 15:59, , 2F
你做這種事他可以假裝他好好的
12/27 15:59, 2F

12/27 16:00, , 3F
os new給你的記憶體範圍可能比較大一點
12/27 16:00, 3F

12/27 16:01, , 4F
或者他沒做存取檢查(VC好像只擋超過0xC000000的)
12/27 16:01, 4F

12/27 16:02, , 5F
delete的時候os才會知道你想free一塊他沒給你的記憶體
12/27 16:02, 5F

12/27 16:02, , 6F
然後這時候os不見得要做exception所以catch不到東西
12/27 16:02, 6F

12/27 16:05, , 7F
#15690 之前問的 以t大解釋似乎沒有辦法理解他怎delete時候
12/27 16:05, 7F

12/27 16:05, , 8F
知道有非法的存取過...
12/27 16:05, 8F

12/27 16:11, , 9F
看錯了我沒仔細看你的code
12/27 16:11, 9F

12/27 16:12, , 10F
以vc2010來說,你new東西的時候他會在後面偷塞一段東西
12/27 16:12, 10F

12/27 16:13, , 11F
delete的時候再檢查這段東西是不是一樣
12/27 16:13, 11F

12/27 16:14, , 12F
因為陣列超界是常見錯誤所以debug的時候他幫你檢查
12/27 16:14, 12F

12/27 16:16, , 13F
run release也是壞掉..他是怎麼判斷我亂改東西呢
12/27 16:16, 13F

12/27 16:16, , 14F
總之這全部都是undefined behavior
12/27 16:16, 14F

12/27 16:17, , 15F
你不能期望他幫你作什麼
12/27 16:17, 15F

12/27 16:22, , 16F
我試了一下release *ptr==5566;這邊就掛了
12/27 16:22, 16F

12/27 16:22, , 17F
然後debbuger下的release他似乎還是幫你作檢查
12/27 16:22, 17F

12/27 16:23, , 18F
debbuger可以把new delete的函數偷偷換掉
12/27 16:23, 18F

12/27 17:07, , 19F
所以這種error無法handle 只能讓程式 當掉嗎?
12/27 17:07, 19F

12/27 17:07, , 20F
有沒有甚麼優雅的 handle方式
12/27 17:07, 20F

12/27 17:11, , 21F
這一般算fatal error
12/27 17:11, 21F

12/27 17:11, , 22F
偵測到一個錯誤不代表只有一個錯誤
12/27 17:11, 22F

12/27 17:11, , 23F
他只能假設你沒救了把你關掉
12/27 17:11, 23F

12/27 17:12, , 24F
這種error handle的方式叫做「不要讓他發生」
12/27 17:12, 24F

12/27 17:13, , 25F
資料寫入前你就應該先檢查大小 自己丟exception
12/27 17:13, 25F

12/27 17:52, , 26F
補一下原po參考的文章 : #1F46xL9_ 然後..
12/27 17:52, 26F

12/27 17:53, , 27F
其實第一個問題也是某科技公司的面試題,為何某些debugger
12/27 17:53, 27F

12/27 17:54, , 28F
可以抓取到 int x[100]; x[101]=20; 這種逾界問題.
12/27 17:54, 28F

12/27 17:56, , 29F
然後問這問題有沒有辦法自己用簡單方式動手作之類的..
12/27 17:56, 29F

12/27 18:36, , 30F
動手做?? 有解答嗎@@ 這種stack out of bound 好像不會盪?
12/27 18:36, 30F

12/27 18:38, , 31F
我VC只有在debug mode才會被檢查出來@@
12/27 18:38, 31F

12/27 18:43, , 32F
這不是用vector::at()就好了嗎 它幫你做bound check
12/27 18:43, 32F

12/27 18:47, , 33F
stack好像不靠compiler動手腳很難處理?
12/27 18:47, 33F

12/27 18:53, , 34F
話說回來,為什麼原po那麼執著於undefined behavior
12/27 18:53, 34F

12/27 18:54, , 35F
同樣的事情換個平台你又會遇到不一樣的行為
12/27 18:54, 35F

12/27 18:56, , 36F
就算你知道底層記憶體的實作細節 也應該把它當黑盒子
12/27 18:56, 36F

12/27 19:04, , 37F
@littleshan ~ 簡單的說,那次面談有提到 dbg_malloc,但一
12/27 19:04, 37F

12/27 19:05, , 38F
般 dbg_malloc 都是查 mem.leak,問有沒有辦法check bound.
12/27 19:05, 38F

12/27 19:06, , 39F
然後 stack 我也覺得是無解,heap的話當時我給的sol很搞剛,
12/27 19:06, 39F

12/27 19:08, , 40F
又不一定能work,回家想想大概也是從 compiler 動手腳 @@
12/27 19:08, 40F

12/27 19:11, , 41F
當你要做黑黑的事情的時候就需要去了解它的behavior了 (誤
12/27 19:11, 41F
文章代碼(AID): #1Gs_iv7a (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1Gs_iv7a (C_and_CPP)