[問題] 陣列 Runtime error

看板C_and_CPP (C/C++)作者 (天下紅雨)時間9年前 (2017/03/01 13:32), 編輯推噓8(8030)
留言38則, 9人參與, 最新討論串1/1
開發平台(Platform): (Ex: Win10, Linux, ...) Win7 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) Dev_CPP 問題(Question): 假如先宣告一陣列為: char a[10]; // a[0]~a[9] 使用 for(int i=0; a[i] ; i++) 如上在 i = 10 時 , a[i] 會存取到 a[10] 之非法記憶體 而 break 掉 但不會發生 runtime error. 但在 使用 if(a[10]) 作為判斷時 一樣存取到 a[10] 之非法記憶體 此時即會造成 runtime error. 想請問這兩者之間的差別 還有第一個for的用法是否有其風險在 謝謝大家 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 120.108.205.21 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1488346376.A.2D8.html

03/01 13:41, , 1F
我不知道他們之間的差別,但是我只知道他們的共同點
03/01 13:41, 1F

03/01 13:42, , 2F
我可以說這個問題很沒營養嗎,都知道是非法位址了
03/01 13:42, 2F

03/01 13:42, , 3F
就是你完全不需要知道一個非法的行為討論的必要性
03/01 13:42, 3F

03/01 13:42, , 4F
還問有沒有風險
03/01 13:42, 4F

03/01 13:43, , 5F
第一個沒當是運氣,剛好有分配這個位址的空間
03/01 13:43, 5F

03/01 13:45, , 6F
使用非法記憶體沒當場出錯絕對是運氣不好 真的別這樣用
03/01 13:45, 6F

03/01 13:49, , 7F
除非你是要用debugger直接分析記憶體,研究存取非法
03/01 13:49, 7F

03/01 13:49, , 8F
位址導致的結果,否則不要幹這種事
03/01 13:49, 8F

03/01 14:11, , 9F
你闖進不是你的房間,裡面有沒有人砍死你不知道XD
03/01 14:11, 9F

03/01 16:02, , 10F
我想a[10]應該是可以讀取的,且不會error
03/01 16:02, 10F

03/01 16:03, , 11F
寫入的話,應該要看寫到什麼地方,有機會造成錯誤
03/01 16:03, 11F

03/01 16:03, , 12F
Undefined behavior 無法確定會發生啥事 就不要這樣搞
03/01 16:03, 12F

03/01 16:03, , 13F
依賴這種行為沒啥意義
03/01 16:03, 13F

03/01 16:03, , 14F
而原PO的runtime error應該是stack爆掉了
03/01 16:03, 14F

03/01 16:04, , 15F
跟a[10]存取無關,跟a[10]內容有關
03/01 16:04, 15F

03/01 16:08, , 16F
a[10] == 0, 無限loop, stack爆掉
03/01 16:08, 16F

03/01 16:12, , 17F
又for(;a[i];);又取存到a[11]以上,一定會碰到false
03/01 16:12, 17F

03/01 16:13, , 18F
想研究深入的話,多逆向一些遊戲或軟體就會了
03/01 16:13, 18F

03/02 00:24, , 19F
>stupid0319 a[10] 不能用, a+10 倒是可以拿來比對
03/02 00:24, 19F

03/02 00:24, , 20F
然後 &a[10] == &(*(a+10)) == a+10 所以也沒問題
03/02 00:24, 20F

03/02 00:25, , 21F
這個是所謂 pointer to one-past-end, 可比對不可存取
03/02 00:25, 21F

03/02 00:59, , 22F
第一次碰到 pointer to one-past-end, 沒想過的東西
03/02 00:59, 22F

03/02 01:03, , 23F
照理說a[10]一定會有資料,到底程式會怎跑呢XD
03/02 01:03, 23F

03/02 01:10, , 24F
是a[10]之後回傳的都是陣列最後一個值的意思嗎?
03/02 01:10, 24F

03/02 08:22, , 25F
a[10]等於*(a+10)
03/02 08:22, 25F

03/02 10:04, , 26F
對 a[10] 存取是未定義行為, 但比對指標是否為 a+10 合法
03/02 10:04, 26F

03/02 10:05, , 27F
也就是這是 OK 的: for(char *p = a; p != a+10; p++) {}
03/02 10:05, 27F

03/02 10:06, , 28F
在這樣的迴圈裡面的 p 只會指向 a[0]~a[9]
03/02 10:06, 28F

03/02 10:06, , 29F
所以對其存取通通沒事
03/02 10:06, 29F

03/02 10:07, , 30F
然後因為上面那行等式, a+10 可以改寫成 &a[10] 也是對的
03/02 10:07, 30F

03/02 10:08, , 31F
也就是 a[10] 這樣的型式只在前面有取址時是合法的
03/02 10:08, 31F

03/02 10:08, , 32F
沒有取址的話它不是存就是取都是非法的
03/02 10:08, 32F

03/02 10:31, , 33F
寫遊戲外掛不就是一堆非法行為集合嗎??
03/02 10:31, 33F

03/02 10:35, , 34F
無聊,你拿鑽程式漏洞來跟寫程式比....
03/02 10:35, 34F

03/02 10:36, , 35F
要不要乾脆說拿還沒清空的stack frame來用
03/02 10:36, 35F

03/02 10:39, , 36F
看什麼外掛啊 練功程式不需要寫到非法行為 -_-
03/02 10:39, 36F

03/02 11:00, , 37F
練習開shell阿(′・ω・`)
03/02 11:00, 37F

03/02 11:12, , 38F
還有就是寫GC會有機會這樣做
03/02 11:12, 38F
文章代碼(AID): #1Ojbq8BO (C_and_CPP)
文章代碼(AID): #1Ojbq8BO (C_and_CPP)