作者TFman (天下紅雨)
看板C_and_CPP
標題[問題] 陣列 Runtime error
時間Wed Mar 1 13:32:54 2017
開發平台(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://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1488346376.A.2D8.html
1F:→ Hazukashiine: 我不知道他們之間的差別,但是我只知道他們的共同點 03/01 13:41
2F:→ loveflames: 我可以說這個問題很沒營養嗎,都知道是非法位址了 03/01 13:42
3F:→ Hazukashiine: 就是你完全不需要知道一個非法的行為討論的必要性 03/01 13:42
4F:→ loveflames: 還問有沒有風險 03/01 13:42
5F:→ loveflames: 第一個沒當是運氣,剛好有分配這個位址的空間 03/01 13:43
6F:推 kyfish: 使用非法記憶體沒當場出錯絕對是運氣不好 真的別這樣用 03/01 13:45
7F:→ loveflames: 除非你是要用debugger直接分析記憶體,研究存取非法 03/01 13:49
8F:→ loveflames: 位址導致的結果,否則不要幹這種事 03/01 13:49
9F:推 james732: 你闖進不是你的房間,裡面有沒有人砍死你不知道XD 03/01 14:11
10F:推 stupid0319: 我想a[10]應該是可以讀取的,且不會error 03/01 16:02
11F:→ stupid0319: 寫入的話,應該要看寫到什麼地方,有機會造成錯誤 03/01 16:03
12F:推 steve1012: Undefined behavior 無法確定會發生啥事 就不要這樣搞 03/01 16:03
13F:→ steve1012: 依賴這種行為沒啥意義 03/01 16:03
14F:→ stupid0319: 而原PO的runtime error應該是stack爆掉了 03/01 16:03
15F:→ stupid0319: 跟a[10]存取無關,跟a[10]內容有關 03/01 16:04
16F:推 stupid0319: a[10] == 0, 無限loop, stack爆掉 03/01 16:08
17F:→ stupid0319: 又for(;a[i];);又取存到a[11]以上,一定會碰到false 03/01 16:12
18F:→ stupid0319: 想研究深入的話,多逆向一些遊戲或軟體就會了 03/01 16:13
19F:推 LPH66: >stupid0319 a[10] 不能用, a+10 倒是可以拿來比對 03/02 00:24
20F:→ LPH66: 然後 &a[10] == &(*(a+10)) == a+10 所以也沒問題 03/02 00:24
21F:→ LPH66: 這個是所謂 pointer to one-past-end, 可比對不可存取 03/02 00:25
22F:→ stupid0319: 第一次碰到 pointer to one-past-end, 沒想過的東西 03/02 00:59
23F:→ stupid0319: 照理說a[10]一定會有資料,到底程式會怎跑呢XD 03/02 01:03
24F:→ stupid0319: 是a[10]之後回傳的都是陣列最後一個值的意思嗎? 03/02 01:10
25F:→ loveflames: a[10]等於*(a+10) 03/02 08:22
26F:推 LPH66: 對 a[10] 存取是未定義行為, 但比對指標是否為 a+10 合法 03/02 10:04
27F:→ LPH66: 也就是這是 OK 的: for(char *p = a; p != a+10; p++) {} 03/02 10:05
28F:→ LPH66: 在這樣的迴圈裡面的 p 只會指向 a[0]~a[9] 03/02 10:06
29F:→ LPH66: 所以對其存取通通沒事 03/02 10:06
30F:→ LPH66: 然後因為上面那行等式, a+10 可以改寫成 &a[10] 也是對的 03/02 10:07
31F:→ LPH66: 也就是 a[10] 這樣的型式只在前面有取址時是合法的 03/02 10:08
32F:→ LPH66: 沒有取址的話它不是存就是取都是非法的 03/02 10:08
33F:→ stupid0319: 寫遊戲外掛不就是一堆非法行為集合嗎?? 03/02 10:31
34F:→ loveflames: 無聊,你拿鑽程式漏洞來跟寫程式比.... 03/02 10:35
35F:→ loveflames: 要不要乾脆說拿還沒清空的stack frame來用 03/02 10:36
36F:→ MOONRAKER: 看什麼外掛啊 練功程式不需要寫到非法行為 -_- 03/02 10:39
37F:推 firejox: 練習開shell阿(′・ω・`) 03/02 11:00
38F:→ firejox: 還有就是寫GC會有機會這樣做 03/02 11:12