作者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/cn.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