#include <stdio.h>
#define CHAR_ROW_SIZE 4
int charTable[CHAR_ROW_SIZE ][2] = {
{'X', 'Z'},
{'J', 'L'},
{'F', 'C'},
{'A', 'B'}
};
int main()
{
printf("char element %c\n", charTable[3][1]); //fine
printf("char element %c\n", charTable[3][8]); // accessing 4th row's 9th element which is not valid
printf("char element %c\n", charTable[85][0]);// accessing 86th row's first element which is not valid
return 0;
}
输出:
char element B
char element
char element
据我了解,C \ C ++实际上不对数组进行任何边界检查。取决于操作系统,以确保您正在访问有效的内存。所以这是未定义的行为。
但是在这里我可以看到不同机器上的不变行为。即程序不会随时崩溃。
答案 0 :(得分:5)
但是在这里我可以看到不同机器上的不变行为。即程序不会随时崩溃。
在这里,崩溃(或分段错误)既不是期望的行为也不是保证的行为,其行为是 undefined 。
这里的底线是,未定义的行为是访问超出范围的内存(即,不属于您的进程地址空间的内存位置)。有时,使用UB的代码似乎可以正常工作,没有任何分段错误,产生一些随机值(包括0),使人产生了“工作正常”的错觉,但事实并非如此!
答案 1 :(得分:0)
除调用abort();
的程序外,C标准没有“应崩溃”的程序概念。编写C标准的目的是允许实现以对编译器客户最有用的任何方式处理越界数组访问。取决于客户要完成的工作,最有用的操作方法可能是:
在编写标准时,存在以三种方式表现的实现,以及三种方式中每种方式最有用的程序。该标准的作者并没有试图就哪种方法在任何特定情况下最适合做出任何判断,而是希望任何希望出售编译器的人都将寻求以他们的客户认为最有用的方式来处理代码-一种行之有效的哲学当语言趋势是由注重客户利益的编译器编写者驱动的时候。