在Java中,我们在尝试访问和数组越界时得到一个漂亮的异常,但在C中并非如此:
#include <stdio.h>
int main() {
int x[10] = {1,2,3}; // After the third index, I know that the rest are 0.
int i = 0;
while (i<99) { // Here I exceed the size of the array,
printf("%d",x[i]); // printing non-existent indexes.
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
12300000001021473443840268687241986531780216078041842686812-12686816199941806157
0338438-2199933010019993299657804184019993359001214734438441990611-819265930944-
8192925345321-122881852697619690479012147344384268694020027537742147344384145346
587600214734438400102686884-819226869482003047601567625672026869562002753732-120
02706633004199040214734438402020893505321130682200320201752380100000243875924666
4687366080-21479789413447414207980
Process returned 1 (0x1) execution time : 0.719 s
Press any key to continue.
Run Code Online (Sandbox Code Playgroud)
从技术上讲,究竟发生了什么?它不完全是"int size overflow",对吗?
在ç访问数组边界之外是不确定的行为,结果是不可预知的,它可能会正常工作,它可能赛格故障,等... 草案C99标准中Annex J.2 未定义的行为,并列出了如下的一条:
数组下标超出范围,即使一个对象显然可以使用给定的下标访问(如左边的表达式a [1] [7],给出声明int a [4] [5])(6.5.6).
6.5.6第8节,这是规范性的细节.
另一方面,Java语言规范 部分10.4使得访问数组的界限异常:
在运行时检查所有数组访问; 尝试使用小于零或大于或等于数组长度的索引会导致抛出ArrayIndexOutOfBoundsException.
Java和C有不同的设计理念.Java摒弃了避免未定义行为的方法,而C和C++为实现提供了自由.关于此的一些好文章: