为啥C语言中数组下标越界不报错

首先我们应该清楚,访问数组的本质是,访问一段连续内存中的某个单元,只要这个单元的内存是可用的,那么程序就不会崩溃。而会导致内存不可用的原因,通常是操作系统的内存保护机制,也就是说程序会因为访问未分配给他的内存而崩溃。回到题目,假如a正好也属于程序的可用内存,那么程序就可以执行。题目执行Debug操作时的报错,(从截图就能看出来)并不是程序本身崩溃,而是运行时(Runtime)主动检查出了越界操作而已。事实上,正因为第一段所述原因,多线程编程难以被调试,有时遇到一个Bug,怎么都解不掉,一个星期后却发现问题出在几千行代码以外的地方。线程A有个数组操作越了界,碰巧赋值给内存里线程B的一个变量上。
■网友
未定义行为出现什么后果都有可能程序员的职责是保证不越界而不是追问越界之后会发生什么
■网友
这不是C的特性,这是微软的VC++在编译debug version of binary时可能插入了一些instrument instruction to detect array out of bound at runtime。试试看release version可能就不报错了。这些特性对于实际软件开发可能很有用,对于学习者反而会造成困惑。a运行时没有报错可能是微软认为最常见的C数组越界就是访问a,为了效率只检查这一种情况而不考虑其他情况。
■网友
这是未定义行为,你换个编译器就不是这样了
为啥C语言中数组下标越界不报错

而且少年,这个例子我在VC里跑了一下
【为啥C语言中数组下标越界不报错】 为啥C语言中数组下标越界不报错

可以看到,到return 0之前程序并没有crash

■网友
为了在调试版程序中检测数组越界写入的情况,编译器为数组多分配了四字节内存并在里面存了个特殊的数字,当函数退出时,加了点代码来检查数组尾部的数字是不是当初设置的那个,一旦变了,说明数组被越界访问了。在你的后一个例子里,越过那个特殊区域写了更远的内存,已经超出这种方式的检测能力了。不过,考虑到大部分写越界都是连续的,这种检测机制还是能检测到大部分越界情况的。


    推荐阅读